Skip to content

Commit 7565c52

Browse files
committed
Do not perform IR optimization if only unoptimized IR is requested
1 parent 130eac4 commit 7565c52

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
@@ -4,9 +4,11 @@ Language Features:
44

55

66
Compiler Features:
7+
* Command Line Interface: Do not perform IR optimization when only unoptimized IR is requested.
78
* EVM: Support for the EVM version "Prague".
89
* SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation.
910
* SMTChecker: Replace CVC4 as a possible BMC backend with cvc5.
11+
* Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested.
1012

1113

1214
Bugfixes:

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;
@@ -716,8 +716,8 @@ bool CompilerStack::compile(State _stopAfter)
716716
{
717717
try
718718
{
719-
if ((m_generateEvmBytecode && m_viaIR) || m_generateIR)
720-
generateIR(*contract);
719+
if ((m_generateEvmBytecode && m_viaIR) || m_irGenerationGoal != IRGenerationGoal::NoIR)
720+
generateIR(*contract, (m_generateEvmBytecode && m_viaIR) || m_irGenerationGoal == IRGenerationGoal::Optimized);
721721
if (m_generateEvmBytecode)
722722
{
723723
if (m_viaIR)
@@ -1406,7 +1406,7 @@ void CompilerStack::compileContract(
14061406
assembleYul(_contract, compiler->assemblyPtr(), compiler->runtimeAssemblyPtr());
14071407
}
14081408

1409-
void CompilerStack::generateIR(ContractDefinition const& _contract)
1409+
void CompilerStack::generateIR(ContractDefinition const& _contract, bool _optimized)
14101410
{
14111411
solAssert(m_stackState >= AnalysisSuccessful, "");
14121412

@@ -1424,7 +1424,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
14241424

14251425
std::string dependenciesSource;
14261426
for (auto const& [dependency, referencee]: _contract.annotation().contractDependencies)
1427-
generateIR(*dependency);
1427+
generateIR(*dependency, _optimized);
14281428

14291429
if (!_contract.canBeDeployed())
14301430
return;
@@ -1484,9 +1484,12 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
14841484
);
14851485

14861486
compiledContract.yulIRAst = stack.astJson();
1487-
stack.optimize();
1488-
compiledContract.yulIROptimized = stack.print(this);
1489-
compiledContract.yulIROptimizedAst = stack.astJson();
1487+
if (_optimized)
1488+
{
1489+
stack.optimize();
1490+
compiledContract.yulIROptimized = stack.print(this);
1491+
compiledContract.yulIROptimizedAst = stack.astJson();
1492+
}
14901493
}
14911494

14921495
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.
@@ -513,7 +524,7 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac
513524
ModelCheckerSettings m_modelCheckerSettings;
514525
std::map<std::string, std::set<std::string>> m_requestedContractNames;
515526
bool m_generateEvmBytecode = true;
516-
bool m_generateIR = false;
527+
IRGenerationGoal m_irGenerationGoal = IRGenerationGoal::NoIR;
517528
std::map<std::string, util::h160> m_libraries;
518529
ImportRemapper m_importRemapper;
519530
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
@@ -294,25 +294,26 @@ bool isEvmBytecodeRequested(Json const& _outputSelection)
294294
return false;
295295
}
296296

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

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

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

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

13211322
compilerStack.enableEvmBytecodeGeneration(isEvmBytecodeRequested(_inputsAndSettings.outputSelection));
1322-
compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection));
1323+
compilerStack.enableIRGeneration(irGenerationGoal(_inputsAndSettings.outputSelection));
13231324

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

solc/CommandLineInterface.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,12 +843,14 @@ void CommandLineInterface::compile()
843843
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
844844
if (m_options.output.debugInfoSelection.has_value())
845845
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
846-
m_compiler->enableIRGeneration(
847-
m_options.compiler.outputs.ir ||
848-
m_options.compiler.outputs.irOptimized ||
849-
m_options.compiler.outputs.irAstJson ||
850-
m_options.compiler.outputs.irOptimizedAstJson
851-
);
846+
847+
CompilerStack::IRGenerationGoal irGenerationGoal = CompilerStack::IRGenerationGoal::NoIR;
848+
if (m_options.compiler.outputs.irOptimized || m_options.compiler.outputs.irOptimizedAstJson)
849+
irGenerationGoal = CompilerStack::IRGenerationGoal::Optimized;
850+
else if (m_options.compiler.outputs.ir || m_options.compiler.outputs.irAstJson)
851+
irGenerationGoal = CompilerStack::IRGenerationGoal::Unoptimized;
852+
853+
m_compiler->enableIRGeneration(irGenerationGoal);
852854
m_compiler->enableEvmBytecodeGeneration(
853855
m_options.compiler.estimateGas ||
854856
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)