Skip to content

Commit 5a232b8

Browse files
committed
Do not perform IR optimization if only unoptimized IR is requested
1 parent 5679f42 commit 5a232b8

File tree

18 files changed

+366
-30
lines changed

18 files changed

+366
-30
lines changed

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ Language Features:
77

88

99
Compiler Features:
10+
* Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested.
1011
* Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs.
1112
* EVM: Support for the EVM version "Prague".
1213
* SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation.
1314
* SMTChecker: Replace CVC4 as a possible BMC backend with cvc5.
15+
* Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested.
1416
* Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical.
1517

1618

libsolidity/interface/CompilerStack.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ void CompilerStack::reset(bool _keepSettings)
313313
m_viaIR = false;
314314
m_evmVersion = langutil::EVMVersion();
315315
m_modelCheckerSettings = ModelCheckerSettings{};
316-
m_generateIR = false;
316+
m_irGenerationGoal = IRGenerationGoal::NoIR;
317317
m_revertStrings = RevertStrings::Default;
318318
m_optimiserSettings = OptimiserSettings::minimal();
319319
m_metadataLiteralSources = false;
@@ -728,8 +728,8 @@ bool CompilerStack::compile(State _stopAfter)
728728
{
729729
try
730730
{
731-
if ((m_generateEvmBytecode && m_viaIR) || m_generateIR)
732-
generateIR(*contract);
731+
if ((m_generateEvmBytecode && m_viaIR) || m_irGenerationGoal != IRGenerationGoal::NoIR)
732+
generateIR(*contract, (m_generateEvmBytecode && m_viaIR) || m_irGenerationGoal == IRGenerationGoal::Optimized);
733733
if (m_generateEvmBytecode)
734734
{
735735
if (m_viaIR)
@@ -1402,7 +1402,7 @@ void CompilerStack::compileContract(
14021402
assembleYul(_contract, compiler->assemblyPtr(), compiler->runtimeAssemblyPtr());
14031403
}
14041404

1405-
void CompilerStack::generateIR(ContractDefinition const& _contract)
1405+
void CompilerStack::generateIR(ContractDefinition const& _contract, bool _optimized)
14061406
{
14071407
solAssert(m_stackState >= AnalysisSuccessful, "");
14081408

@@ -1420,7 +1420,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
14201420

14211421
std::string dependenciesSource;
14221422
for (auto const& [dependency, referencee]: _contract.annotation().contractDependencies)
1423-
generateIR(*dependency);
1423+
generateIR(*dependency, _optimized);
14241424

14251425
if (!_contract.canBeDeployed())
14261426
return;
@@ -1480,9 +1480,12 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
14801480
);
14811481

14821482
compiledContract.yulIRAst = stack.astJson();
1483-
stack.optimize();
1484-
compiledContract.yulIROptimized = stack.print(this);
1485-
compiledContract.yulIROptimizedAst = stack.astJson();
1483+
if (_optimized)
1484+
{
1485+
stack.optimize();
1486+
compiledContract.yulIROptimized = stack.print(this);
1487+
compiledContract.yulIROptimizedAst = stack.astJson();
1488+
}
14861489
}
14871490

14881491
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)

libsolidity/interface/CompilerStack.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
126126
SolidityAST,
127127
};
128128

129+
enum class IRGenerationGoal {
130+
NoIR, ///< Do not generate Yul IR.
131+
Unoptimized, ///< Stop after generating unoptimized Yul IR.
132+
Optimized, ///< Generate unoptimized Yul IR and optimize it.
133+
};
134+
129135
/// Creates a new compiler stack.
130136
/// @param _readFile callback used to read files for import statements. Must return
131137
/// and must not emit exceptions.
@@ -193,7 +199,12 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
193199
void enableEvmBytecodeGeneration(bool _enable = true) { m_generateEvmBytecode = _enable; }
194200

195201
/// Enable generation of Yul IR code.
196-
void enableIRGeneration(bool _enable = true) { m_generateIR = _enable; }
202+
/// Note that @a setViaIR(true) overrides this and works as if the goal was set to @a Optimized.
203+
void enableIRGeneration(IRGenerationGoal _goal = IRGenerationGoal::Optimized)
204+
{
205+
solAssert(m_stackState < ParsedAndImported);
206+
m_irGenerationGoal = _goal;
207+
}
197208

198209
/// @arg _metadataLiteralSources When true, store sources as literals in the contract metadata.
199210
/// Must be set before parsing.
@@ -450,7 +461,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
450461

451462
/// Generate Yul IR for a single contract.
452463
/// The IR is stored but otherwise unused.
453-
void generateIR(ContractDefinition const& _contract);
464+
void generateIR(ContractDefinition const& _contract, bool _optimized);
454465

455466
/// Generate EVM representation for a single contract.
456467
/// Depends on output generated by generateIR.
@@ -515,7 +526,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
515526
ModelCheckerSettings m_modelCheckerSettings;
516527
std::map<std::string, std::set<std::string>> m_requestedContractNames;
517528
bool m_generateEvmBytecode = true;
518-
bool m_generateIR = false;
529+
IRGenerationGoal m_irGenerationGoal = IRGenerationGoal::NoIR;
519530
std::map<std::string, util::h160> m_libraries;
520531
ImportRemapper m_importRemapper;
521532
std::map<std::string const, Source> m_sources;

libsolidity/interface/StandardCompiler.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -295,25 +295,26 @@ bool isEvmBytecodeRequested(Json const& _outputSelection)
295295
return false;
296296
}
297297

298-
/// @returns true if any Yul IR was requested. Note that as an exception, '*' does not
299-
/// yet match "ir", "irAst", "irOptimized" or "irOptimizedAst"
300-
bool isIRRequested(Json const& _outputSelection)
298+
/// @returns The requested goal for Yul IR generation inferred from output selection.
299+
/// Note that as an exception, '*' does not yet match "ir", "irAst", "irOptimized" or "irOptimizedAst".
300+
CompilerStack::IRGenerationGoal irGenerationGoal(Json const& _outputSelection)
301301
{
302302
if (!_outputSelection.is_object())
303-
return false;
303+
return CompilerStack::IRGenerationGoal::NoIR;
304304

305+
CompilerStack::IRGenerationGoal goal = CompilerStack::IRGenerationGoal::NoIR;
305306
for (auto const& fileRequests: _outputSelection)
306307
for (auto const& requests: fileRequests)
307308
for (auto const& request: requests)
308-
if (
309-
request == "ir" ||
310-
request == "irAst" ||
311-
request == "irOptimized" ||
312-
request == "irOptimizedAst"
313-
)
314-
return true;
309+
{
310+
if (request == "irOptimized" || request == "irOptimizedAst")
311+
return CompilerStack::IRGenerationGoal::Optimized;
315312

316-
return false;
313+
if (request == "ir" || request == "irAst")
314+
goal = CompilerStack::IRGenerationGoal::Unoptimized;
315+
}
316+
317+
return goal;
317318
}
318319

319320
Json formatLinkReferences(std::map<size_t, std::string> const& linkReferences)
@@ -1320,7 +1321,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu
13201321
compilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings);
13211322

13221323
compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection));
1323-
compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection));
1324+
compilerStack.enableIRGeneration(irGenerationGoal(_inputsAndSettings.outputSelection));
13241325

13251326
Json errors = std::move(_inputsAndSettings.errors);
13261327

solc/CommandLineInterface.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -849,12 +849,14 @@ void CommandLineInterface::compile()
849849
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
850850
if (m_options.output.debugInfoSelection.has_value())
851851
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
852-
m_compiler->enableIRGeneration(
853-
m_options.compiler.outputs.ir ||
854-
m_options.compiler.outputs.irOptimized ||
855-
m_options.compiler.outputs.irAstJson ||
856-
m_options.compiler.outputs.irOptimizedAstJson
857-
);
852+
853+
CompilerStack::IRGenerationGoal irGenerationGoal = CompilerStack::IRGenerationGoal::NoIR;
854+
if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson)
855+
irGenerationGoal = CompilerStack::IRGenerationGoal::Optimized;
856+
else if (m_options.compiler.outputs.ir || m_options.compiler.outputs.irAstJson)
857+
irGenerationGoal = CompilerStack::IRGenerationGoal::Unoptimized;
858+
859+
m_compiler->enableIRGeneration(irGenerationGoal);
858860
m_compiler->enableEvmBytecodeGeneration(
859861
m_options.compiler.estimateGas ||
860862
m_options.compiler.outputs.asm_ ||
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--ir-optimized --optimize --debug-info none
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity *;
3+
4+
contract C {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Optimized IR:
2+
/// @use-src 0:"ir_optimized_with_optimize/input.sol"
3+
object "C_2" {
4+
code {
5+
{
6+
let _1 := memoryguard(0x80)
7+
mstore(64, _1)
8+
if callvalue() { revert(0, 0) }
9+
let _2 := datasize("C_2_deployed")
10+
codecopy(_1, dataoffset("C_2_deployed"), _2)
11+
return(_1, _2)
12+
}
13+
}
14+
/// @use-src 0:"ir_optimized_with_optimize/input.sol"
15+
object "C_2_deployed" {
16+
code { { revert(0, 0) } }
17+
data ".metadata" hex"<BYTECODE REMOVED>"
18+
}
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--ir --optimize --debug-info none
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity *;
3+
4+
contract C {}

0 commit comments

Comments
 (0)