Merge pull request #14355 from ethereum/via-ir-bytecode-comparison

Via IR bytecode comparison
This commit is contained in:
Kamil Śliwak 2023-07-14 17:26:13 +02:00 committed by GitHub
commit e70e595ce7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 9 deletions

View File

@ -88,6 +88,7 @@ commands:
steps: steps:
- run: - run:
name: Generate bytecode reports for the selected preset name: Generate bytecode reports for the selected preset
no_output_timeout: 30m
command: | command: |
.circleci/parallel_bytecode_report.sh \ .circleci/parallel_bytecode_report.sh \
"<< parameters.label >>" \ "<< parameters.label >>" \
@ -227,6 +228,8 @@ defaults:
PRESETS: PRESETS:
legacy-optimize legacy-optimize
legacy-no-optimize legacy-no-optimize
via-ir-optimize
via-ir-no-optimize
- bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix - bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix
parameters: parameters:
@ -234,6 +237,8 @@ defaults:
# NOTE: Keep in sync with preset list in bytecode_compare_env_presets # NOTE: Keep in sync with preset list in bytecode_compare_env_presets
- legacy-optimize - legacy-optimize
- legacy-no-optimize - legacy-no-optimize
- via-ir-optimize
- via-ir-no-optimize
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Artifacts Templates # Artifacts Templates

View File

@ -44,6 +44,9 @@ cd test-cases/
echo "Preparing input files" echo "Preparing input files"
python3 ../scripts/isolate_tests.py ../test/ python3 ../scripts/isolate_tests.py ../test/
# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583
rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol
if [[ $binary_type == native ]]; then if [[ $binary_type == native ]]; then
interface=$(echo -e "standard-json\ncli" | circleci tests split) interface=$(echo -e "standard-json\ncli" | circleci tests split)
echo "Selected interface: ${interface}" echo "Selected interface: ${interface}"

View File

@ -5,8 +5,10 @@ const fs = require('fs')
const compiler = require('solc') const compiler = require('solc')
SETTINGS_PRESETS = { SETTINGS_PRESETS = {
'legacy-optimize': {optimize: true}, 'legacy-optimize': {optimize: true, viaIR: false},
'legacy-no-optimize': {optimize: false}, 'legacy-no-optimize': {optimize: false, viaIR: false},
'via-ir-optimize': {optimize: true, viaIR: true},
'via-ir-no-optimize': {optimize: false, viaIR: true},
} }
function loadSource(sourceFileName, stripSMTPragmas) function loadSource(sourceFileName, stripSMTPragmas)
@ -67,6 +69,8 @@ for (const preset of presets)
}, },
settings: { settings: {
optimizer: {enabled: settings.optimize}, optimizer: {enabled: settings.optimize},
// NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.
viaIR: settings.viaIR ? true : undefined,
outputSelection: {'*': {'*': ['evm.bytecode.object', 'metadata']}} outputSelection: {'*': {'*': ['evm.bytecode.object', 'metadata']}}
} }
} }
@ -96,7 +100,7 @@ for (const preset of presets)
// JSON interface still returns contract metadata in case of an internal compiler error while // JSON interface still returns contract metadata in case of an internal compiler error while
// CLI interface does not. To make reports comparable we must force this case to be detected as // CLI interface does not. To make reports comparable we must force this case to be detected as
// an error in both cases. // an error in both cases.
if (['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError'].includes(error['type'])) if (['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException'].includes(error['type']))
{ {
internalCompilerError = true internalCompilerError = true
break break

View File

@ -29,6 +29,8 @@ class CompilerInterface(Enum):
class SettingsPreset(Enum): class SettingsPreset(Enum):
LEGACY_OPTIMIZE = 'legacy-optimize' LEGACY_OPTIMIZE = 'legacy-optimize'
LEGACY_NO_OPTIMIZE = 'legacy-no-optimize' LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'
VIA_IR_OPTIMIZE = 'via-ir-optimize'
VIA_IR_NO_OPTIMIZE = 'via-ir-no-optimize'
class SMTUse(Enum): class SMTUse(Enum):
@ -40,12 +42,15 @@ class SMTUse(Enum):
@dataclass(frozen=True) @dataclass(frozen=True)
class CompilerSettings: class CompilerSettings:
optimize: bool optimize: bool
via_ir: bool
@staticmethod @staticmethod
def from_preset(preset: SettingsPreset): def from_preset(preset: SettingsPreset):
return { return {
SettingsPreset.LEGACY_OPTIMIZE: CompilerSettings(optimize=True), SettingsPreset.LEGACY_OPTIMIZE: CompilerSettings(optimize=True, via_ir=False),
SettingsPreset.LEGACY_NO_OPTIMIZE: CompilerSettings(optimize=False), SettingsPreset.LEGACY_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=False),
SettingsPreset.VIA_IR_OPTIMIZE: CompilerSettings(optimize=True, via_ir=True),
SettingsPreset.VIA_IR_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=True),
}[preset] }[preset]
@ -152,7 +157,7 @@ def parse_standard_json_output(source_file_name: Path, standard_json_output: str
# CLI interface does not. To make reports comparable we must force this case to be detected as # CLI interface does not. To make reports comparable we must force this case to be detected as
# an error in both cases. # an error in both cases.
internal_compiler_error = any( internal_compiler_error = any(
error['type'] in ['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError'] error['type'] in ['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException']
for error in decoded_json_output.get('errors', {}) for error in decoded_json_output.get('errors', {})
) )
@ -224,6 +229,8 @@ def prepare_compiler_input(
}, },
'settings': { 'settings': {
'optimizer': {'enabled': settings.optimize}, 'optimizer': {'enabled': settings.optimize},
# NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.
**({'viaIR': True} if settings.via_ir else {}),
'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}}, 'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}},
} }
} }
@ -243,6 +250,8 @@ def prepare_compiler_input(
compiler_options.append('--optimize') compiler_options.append('--optimize')
elif force_no_optimize_yul: elif force_no_optimize_yul:
compiler_options.append('--no-optimize-yul') compiler_options.append('--no-optimize-yul')
if settings.via_ir:
compiler_options.append('--via-ir')
if smt_use == SMTUse.DISABLE: if smt_use == SMTUse.DISABLE:
compiler_options += ['--model-checker-engine', 'none'] compiler_options += ['--model-checker-engine', 'none']

View File

@ -265,6 +265,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
}, },
'settings': { 'settings': {
'optimizer': {'enabled': True}, 'optimizer': {'enabled': True},
'viaIR': True,
'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}}, 'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}},
'modelChecker': {'engine': 'none'}, 'modelChecker': {'engine': 'none'},
} }
@ -273,7 +274,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
(command_line, compiler_input) = prepare_compiler_input( (command_line, compiler_input) = prepare_compiler_input(
Path('solc'), Path('solc'),
SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH, SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH,
preset=SettingsPreset.LEGACY_OPTIMIZE, preset=SettingsPreset.VIA_IR_OPTIMIZE,
force_no_optimize_yul=False, force_no_optimize_yul=False,
interface=CompilerInterface.STANDARD_JSON, interface=CompilerInterface.STANDARD_JSON,
smt_use=SMTUse.DISABLE, smt_use=SMTUse.DISABLE,
@ -317,7 +318,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
(command_line, compiler_input) = prepare_compiler_input( (command_line, compiler_input) = prepare_compiler_input(
Path('solc'), Path('solc'),
SMT_SMOKE_TEST_SOL_PATH, SMT_SMOKE_TEST_SOL_PATH,
preset=SettingsPreset.LEGACY_OPTIMIZE, preset=SettingsPreset.VIA_IR_OPTIMIZE,
force_no_optimize_yul=False, force_no_optimize_yul=False,
interface=CompilerInterface.CLI, interface=CompilerInterface.CLI,
smt_use=SMTUse.PRESERVE, smt_use=SMTUse.PRESERVE,
@ -326,7 +327,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
self.assertEqual( self.assertEqual(
command_line, command_line,
['solc', str(SMT_SMOKE_TEST_SOL_PATH), '--bin', '--optimize'], ['solc', str(SMT_SMOKE_TEST_SOL_PATH), '--bin', '--optimize', '--via-ir'],
) )
self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE) self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE)