new container

This commit is contained in:
Daniel Kirchner
2023-01-05 20:05:11 +01:00
parent b32ae4715b
commit 98289270da
9 changed files with 105 additions and 35 deletions
+2 -1
View File
@@ -101,7 +101,8 @@ public:
/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.
virtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = "") = 0;
virtual FunctionID createFunction(uint8_t _args, uint8_t _rets) = 0;
virtual FunctionID createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackHeight) = 0;
virtual void setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight) = 0;
virtual void beginFunction(FunctionID _functionID) = 0;
virtual void endFunction() = 0;
+7 -2
View File
@@ -146,9 +146,14 @@ pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
}
AbstractAssembly::FunctionID EthAssemblyAdapter::createFunction(uint8_t _args, uint8_t _rets)
AbstractAssembly::FunctionID EthAssemblyAdapter::createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackArgs)
{
return m_assembly.createFunction(_args, _rets);
return m_assembly.createFunction(_args, _rets, _maxStackArgs);
}
void EthAssemblyAdapter::setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight)
{
m_assembly.setMaxStackHeight(_functionID, _maxStackHeight);
}
void EthAssemblyAdapter::beginFunction(AbstractAssembly::FunctionID _functionID)
+2 -1
View File
@@ -56,7 +56,8 @@ public:
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
void appendAssemblySize() override;
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = {}) override;
AbstractAssembly::FunctionID createFunction(uint8_t _args, uint8_t _rets) override;
AbstractAssembly::FunctionID createFunction(uint8_t _args, uint8_t _rets, uint16_t _maxStackHeight) override;
void setMaxStackHeight(FunctionID _functionID, uint16_t _maxStackHeight) override;
void beginFunction(AbstractAssembly::FunctionID _functionID) override;
void endFunction() override;
void appendFunctionCall(FunctionID _functionID) override;
+1 -1
View File
@@ -104,7 +104,7 @@ pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::cr
return {};
}
AbstractAssembly::FunctionID NoOutputAssembly::createFunction(uint8_t _args, uint8_t _rets)
AbstractAssembly::FunctionID NoOutputAssembly::createFunction(uint8_t _args, uint8_t _rets, uint16_t)
{
yulAssert(m_context->numFunctions <= std::numeric_limits<AbstractAssembly::FunctionID>::max());
AbstractAssembly::FunctionID id = static_cast<AbstractAssembly::FunctionID>(m_context->numFunctions++);
+2 -1
View File
@@ -74,7 +74,8 @@ public:
void appendAssemblySize() override;
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::optional<uint8_t> _eofVersion, std::string _name = "") override;
FunctionID createFunction(uint8_t _args, uint8_t rets) override;
FunctionID createFunction(uint8_t _args, uint8_t rets, uint16_t _maxStackHeight) override;
void setMaxStackHeight(AbstractAssembly::FunctionID, uint16_t) override {}
void beginFunction(FunctionID) override;
void endFunction() override;
void appendFunctionCall(FunctionID _functionID) override;
@@ -40,6 +40,54 @@ using namespace solidity;
using namespace solidity::yul;
using namespace std;
namespace {
uint16_t getMaxStackHeight(CFG::BasicBlock const& _block, StackLayout const& _stackLayout)
{
size_t maxStackHeight = 0;
std::list<CFG::BasicBlock const*> toVisit;
std::set<CFG::BasicBlock const*> visited;
toVisit.push_back(&_block);
while(!toVisit.empty())
{
CFG::BasicBlock const* block = toVisit.back();
toVisit.pop_back();
if (!visited.insert(block).second)
continue;
auto& blockInfo = _stackLayout.blockInfos.at(block);
maxStackHeight = std::max(maxStackHeight, blockInfo.entryLayout.size());
for (auto const& operation: block->operations)
{
size_t entryLayout = _stackLayout.operationEntryLayout.at(&operation).size();
maxStackHeight = std::max(maxStackHeight, entryLayout);
size_t exitLayout = entryLayout - operation.input.size() + operation.output.size();
maxStackHeight = std::max(maxStackHeight, exitLayout);
}
maxStackHeight = std::max(maxStackHeight, blockInfo.exitLayout.size());
std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) {},
[&](CFG::BasicBlock::Jump const& _jump) { toVisit.emplace_back(_jump.target); },
[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)
{
toVisit.emplace_back(_conditionalJump.zero);
toVisit.emplace_back(_conditionalJump.nonZero);
},
[&](CFG::BasicBlock::FunctionReturn const&) {},
[&](CFG::BasicBlock::Terminated const&) {}
}, block->exit);
}
yulAssert(maxStackHeight <= 0xFFFF);
return static_cast<uint16_t>(maxStackHeight);
}
}
vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo,
@@ -55,6 +103,8 @@ vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
StackLayout stackLayout = StackLayoutGenerator::run(*dfg);
if (dfg->useFunctions)
{
_assembly.setMaxStackHeight(0, getMaxStackHeight(*dfg->entry, stackLayout));
for (Scope::Function const* function: dfg->functions)
{
auto const& info = dfg->functionInfo.at(function);
@@ -62,10 +112,12 @@ vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
yulAssert(info.returnVariables.size() <= 0xFF);
auto functionID = _assembly.createFunction(
static_cast<uint8_t>(info.parameters.size()),
static_cast<uint8_t>(info.returnVariables.size())
static_cast<uint8_t>(info.returnVariables.size()),
getMaxStackHeight(*info.entry, stackLayout)
);
_builtinContext.functionIDs[function] = functionID;
}
}
OptimizedEVMCodeTransform optimizedCodeTransform(
_assembly,