mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add inlining for old optimizer.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <libevmasm/CommonSubexpressionEliminator.h>
|
||||
#include <libevmasm/PeepholeOptimiser.h>
|
||||
#include <libevmasm/Inliner.h>
|
||||
#include <libevmasm/JumpdestRemover.h>
|
||||
#include <libevmasm/ControlFlowGraph.h>
|
||||
#include <libevmasm/BlockDeduplicator.h>
|
||||
@@ -1233,7 +1234,17 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies)
|
||||
main.append(t1.toSubAssemblyTag(subId));
|
||||
main.append(u256(8));
|
||||
|
||||
main.optimise(true, solidity::test::CommonOptions::get().evmVersion(), false, 200);
|
||||
Assembly::OptimiserSettings settings;
|
||||
settings.isCreation = false;
|
||||
settings.runInliner = false;
|
||||
settings.runJumpdestRemover = true;
|
||||
settings.runPeephole = true;
|
||||
settings.runDeduplicate = true;
|
||||
settings.runCSE = true;
|
||||
settings.runConstantOptimiser = true;
|
||||
settings.evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
||||
settings.expectedExecutionsPerDeployment = 200;
|
||||
main.optimise(settings);
|
||||
|
||||
AssemblyItems expectationMain{
|
||||
AssemblyItem(PushSubSize, 0),
|
||||
@@ -1467,6 +1478,165 @@ BOOST_AUTO_TEST_CASE(cse_replace_too_large_shift)
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner)
|
||||
{
|
||||
AssemblyItem jumpInto{Instruction::JUMP};
|
||||
jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);
|
||||
AssemblyItem jumpOutOf{Instruction::JUMP};
|
||||
jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
AssemblyItem(PushTag, 2),
|
||||
jumpInto,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::SWAP1,
|
||||
jumpOutOf,
|
||||
};
|
||||
AssemblyItems expectation{
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::SWAP1,
|
||||
Instruction::JUMP,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::SWAP1,
|
||||
jumpOutOf,
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
expectation.begin(), expectation.end()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner_no_inline_type)
|
||||
{
|
||||
// Will not inline due to jump types.
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
AssemblyItem(PushTag, 2),
|
||||
Instruction::JUMP,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::SWAP1,
|
||||
Instruction::JUMP,
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
items.begin(), items.end()
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner_no_inline)
|
||||
{
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMP,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::JUMPI,
|
||||
Instruction::JUMP,
|
||||
};
|
||||
AssemblyItems expectation{
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMP,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::CALLVALUE,
|
||||
Instruction::JUMPI,
|
||||
Instruction::JUMP,
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
expectation.begin(), expectation.end()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner_single_jump)
|
||||
{
|
||||
AssemblyItem jumpInto{Instruction::JUMP};
|
||||
jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);
|
||||
AssemblyItem jumpOutOf{Instruction::JUMP};
|
||||
jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
AssemblyItem(PushTag, 2),
|
||||
jumpInto,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
jumpOutOf,
|
||||
};
|
||||
AssemblyItems expectation{
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMP,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
jumpOutOf,
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
expectation.begin(), expectation.end()
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner_end_of_bytecode)
|
||||
{
|
||||
AssemblyItem jumpInto{Instruction::JUMP};
|
||||
jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);
|
||||
// Cannot inline, since the block at Tag_2 does not end in a jump.
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
AssemblyItem(PushTag, 2),
|
||||
jumpInto,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
items.begin(), items.end()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inliner_cse_break)
|
||||
{
|
||||
AssemblyItem jumpInto{Instruction::JUMP};
|
||||
jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);
|
||||
AssemblyItem jumpOutOf{Instruction::JUMP};
|
||||
jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);
|
||||
// Could be inlined, but we only consider non-CSE-breaking blocks ending in JUMP so far.
|
||||
AssemblyItems items{
|
||||
AssemblyItem(PushTag, 1),
|
||||
AssemblyItem(PushTag, 2),
|
||||
jumpInto,
|
||||
AssemblyItem(Tag, 1),
|
||||
Instruction::STOP,
|
||||
AssemblyItem(Tag, 2),
|
||||
Instruction::STOP, // CSE breaking instruction
|
||||
jumpOutOf
|
||||
};
|
||||
Inliner{items, {}, 200, false, {}}.optimise();
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
items.begin(), items.end(),
|
||||
items.begin(), items.end()
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // end namespaces
|
||||
|
||||
Reference in New Issue
Block a user