Skip to content

Commit

Permalink
emit debug info is not an optimizer setting but a debug info config
Browse files Browse the repository at this point in the history
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
  • Loading branch information
xermicus committed Nov 21, 2024
1 parent bb50491 commit 6b4284c
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 123 deletions.
91 changes: 56 additions & 35 deletions crates/llvm-context/src/debug_config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,52 @@ use self::ir_type::IRType;
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct DebugConfig {
/// The directory to dump the IRs to.
pub output_directory: PathBuf,
pub output_directory: Option<PathBuf>,
/// Whether debug info should be emitted.
pub emit_debug_info: bool,
}

impl DebugConfig {
/// A shortcut constructor.
pub fn new(output_directory: PathBuf) -> Self {
Self { output_directory }
pub const fn new(output_directory: Option<PathBuf>, emit_debug_info: bool) -> Self {
Self {
output_directory,
emit_debug_info,
}
}

/// Dumps the Yul IR.
pub fn dump_yul(&self, contract_path: &str, code: &str) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::Yul);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let mut file_path = output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::Yul);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
}

Ok(())
}

/// Dumps the EVM legacy assembly IR.
pub fn dump_evmla(&self, contract_path: &str, code: &str) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::EVMLA);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let mut file_path = output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::EVMLA);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
}

Ok(())
}

/// Dumps the Ethereal IR.
pub fn dump_ethir(&self, contract_path: &str, code: &str) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::EthIR);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let mut file_path = output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::EthIR);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
}

Ok(())
}
Expand All @@ -58,12 +69,15 @@ impl DebugConfig {
contract_path: &str,
module: &inkwell::module::Module,
) -> anyhow::Result<()> {
let llvm_code = module.print_to_string().to_string();

let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, Some("unoptimized"), IRType::LLVM);
file_path.push(full_file_name);
std::fs::write(file_path, llvm_code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let llvm_code = module.print_to_string().to_string();

let mut file_path = output_directory.to_owned();
let full_file_name =
Self::full_file_name(contract_path, Some("unoptimized"), IRType::LLVM);
file_path.push(full_file_name);
std::fs::write(file_path, llvm_code)?;
}

Ok(())
}
Expand All @@ -74,22 +88,27 @@ impl DebugConfig {
contract_path: &str,
module: &inkwell::module::Module,
) -> anyhow::Result<()> {
let llvm_code = module.print_to_string().to_string();

let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, Some("optimized"), IRType::LLVM);
file_path.push(full_file_name);
std::fs::write(file_path, llvm_code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let llvm_code = module.print_to_string().to_string();

let mut file_path = output_directory.to_owned();
let full_file_name =
Self::full_file_name(contract_path, Some("optimized"), IRType::LLVM);
file_path.push(full_file_name);
std::fs::write(file_path, llvm_code)?;
}

Ok(())
}

/// Dumps the assembly.
pub fn dump_assembly(&self, contract_path: &str, code: &str) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::Assembly);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let mut file_path = output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::Assembly);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
}

Ok(())
}
Expand All @@ -102,10 +121,12 @@ impl DebugConfig {
contract_suffix: Option<&str>,
stage_json: &Vec<u8>,
) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, contract_suffix, IRType::JSON);
file_path.push(full_file_name);
std::fs::write(file_path, stage_json)?;
if let Some(output_directory) = self.output_directory.as_ref() {
let mut file_path = output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, contract_suffix, IRType::JSON);
file_path.push(full_file_name);
std::fs::write(file_path, stage_json)?;
}

Ok(())
}
Expand Down
14 changes: 0 additions & 14 deletions crates/llvm-context/src/optimizer/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ pub struct Settings {
pub is_verify_each_enabled: bool,
/// Whether the LLVM `debug logging` option is enabled.
pub is_debug_logging_enabled: bool,

/// Whether to generate source-level debug information.
pub emit_debug_info: bool,
}

impl Settings {
Expand All @@ -47,8 +44,6 @@ impl Settings {

is_verify_each_enabled: false,
is_debug_logging_enabled: false,

emit_debug_info: false,
}
}

Expand All @@ -60,8 +55,6 @@ impl Settings {

is_verify_each_enabled: bool,
is_debug_logging_enabled: bool,

emit_debug_info: bool,
) -> Self {
Self {
level_middle_end,
Expand All @@ -72,8 +65,6 @@ impl Settings {

is_verify_each_enabled,
is_debug_logging_enabled,

emit_debug_info,
}
}

Expand Down Expand Up @@ -215,11 +206,6 @@ impl Settings {
pub fn is_fallback_to_size_enabled(&self) -> bool {
self.is_fallback_to_size_enabled
}

/// Whether source-level debug information should be emitted.
pub fn emit_debug_info(&self) -> bool {
self.emit_debug_info
}
}

impl PartialEq for Settings {
Expand Down
27 changes: 16 additions & 11 deletions crates/llvm-context/src/polkavm/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ where
/// The debug info of the current module.
debug_info: Option<DebugInfo<'ctx>>,
/// The debug configuration telling whether to dump the needed IRs.
debug_config: Option<DebugConfig>,
debug_config: DebugConfig,

/// The Solidity data.
solidity_data: Option<SolidityData>,
Expand Down Expand Up @@ -209,8 +209,7 @@ where
optimizer: Optimizer,
dependency_manager: Option<D>,
include_metadata_hash: bool,
debug_info: Option<DebugInfo<'ctx>>,
debug_config: Option<DebugConfig>,
debug_config: DebugConfig,
) -> Self {
Self::link_stdlib_module(llvm, &module);
Self::link_polkavm_imports(llvm, &module);
Expand All @@ -219,6 +218,11 @@ where

let intrinsics = Intrinsics::new(llvm, &module);
let llvm_runtime = LLVMRuntime::new(llvm, &module, &optimizer);
let debug_info = debug_config.emit_debug_info.then(|| {
let debug_info = DebugInfo::new(&module);
debug_info.initialize_module(llvm, &module);
debug_info
});

Self {
llvm,
Expand Down Expand Up @@ -259,9 +263,9 @@ where
let target_machine = TargetMachine::new(Target::PVM, self.optimizer.settings())?;
target_machine.set_target_data(self.module());

if let Some(ref debug_config) = self.debug_config {
debug_config.dump_llvm_ir_unoptimized(contract_path, self.module())?;
}
self.debug_config
.dump_llvm_ir_unoptimized(contract_path, self.module())?;

self.verify().map_err(|error| {
anyhow::anyhow!(
"The contract `{}` unoptimized LLVM IR verification error: {}",
Expand All @@ -279,9 +283,10 @@ where
error
)
})?;
if let Some(ref debug_config) = self.debug_config {
debug_config.dump_llvm_ir_optimized(contract_path, self.module())?;
}

self.debug_config
.dump_llvm_ir_optimized(contract_path, self.module())?;

self.verify().map_err(|error| {
anyhow::anyhow!(
"The contract `{}` optimized LLVM IR verification error: {}",
Expand Down Expand Up @@ -648,8 +653,8 @@ where
}

/// Returns the debug config reference.
pub fn debug_config(&self) -> Option<&DebugConfig> {
self.debug_config.as_ref()
pub fn debug_config(&self) -> &DebugConfig {
&self.debug_config
}

/// Appends a new basic block to the current function.
Expand Down
2 changes: 1 addition & 1 deletion crates/llvm-context/src/polkavm/context/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn create_context(
let module = llvm.create_module("test");
let optimizer = Optimizer::new(optimizer_settings);

Context::<DummyDependency>::new(llvm, module, optimizer, None, true, None, None)
Context::<DummyDependency>::new(llvm, module, optimizer, None, true, Default::default())
}

#[test]
Expand Down
10 changes: 4 additions & 6 deletions crates/llvm-context/src/polkavm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn build_assembly_text(
contract_path: &str,
bytecode: &[u8],
metadata_hash: Option<[u8; revive_common::BYTE_LENGTH_WORD]>,
debug_config: Option<&DebugConfig>,
debug_config: &DebugConfig,
) -> anyhow::Result<Build> {
let program_blob = ProgramBlob::parse(bytecode.into())
.map_err(anyhow::Error::msg)
Expand All @@ -49,9 +49,7 @@ pub fn build_assembly_text(
format!("Failed to convert disassembled code to string for contract: {contract_path}")
})?;

if let Some(debug_config) = debug_config {
debug_config.dump_assembly(contract_path, &assembly_text)?;
}
debug_config.dump_assembly(contract_path, &assembly_text)?;

Ok(Build::new(
assembly_text.to_owned(),
Expand Down Expand Up @@ -98,7 +96,7 @@ pub trait Dependency {
path: &str,
optimizer_settings: OptimizerSettings,
include_metadata_hash: bool,
debug_config: Option<DebugConfig>,
debug_config: DebugConfig,
) -> anyhow::Result<String>;

/// Resolves a full contract path.
Expand All @@ -118,7 +116,7 @@ impl Dependency for DummyDependency {
_path: &str,
_optimizer_settings: OptimizerSettings,
_include_metadata_hash: bool,
_debug_config: Option<DebugConfig>,
_debug_config: DebugConfig,
) -> anyhow::Result<String> {
Ok(String::new())
}
Expand Down
23 changes: 14 additions & 9 deletions crates/solidity/src/evmla/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,10 @@ where
) -> anyhow::Result<()> {
let full_path = self.full_path().to_owned();

if let Some(debug_config) = context.debug_config() {
debug_config.dump_evmla(full_path.as_str(), self.to_string().as_str())?;
}
context
.debug_config()
.dump_evmla(full_path.as_str(), self.to_string().as_str())?;

let deploy_code_blocks = EtherealIR::get_blocks(
context.evmla().version.to_owned(),
revive_llvm_context::PolkaVMCodeType::Deploy,
Expand All @@ -228,9 +229,11 @@ where
.ok_or_else(|| anyhow::anyhow!("Runtime code data not found"))?
.remove("0")
.expect("Always exists");
if let Some(debug_config) = context.debug_config() {
debug_config.dump_evmla(full_path.as_str(), data.to_string().as_str())?;
}

context
.debug_config()
.dump_evmla(full_path.as_str(), data.to_string().as_str())?;

let runtime_code_instructions = match data {
Data::Assembly(assembly) => assembly
.code
Expand All @@ -253,9 +256,11 @@ where
blocks.extend(runtime_code_blocks);
let mut ethereal_ir =
EtherealIR::new(context.evmla().version.to_owned(), extra_metadata, blocks)?;
if let Some(debug_config) = context.debug_config() {
debug_config.dump_ethir(full_path.as_str(), ethereal_ir.to_string().as_str())?;
}

context
.debug_config()
.dump_ethir(full_path.as_str(), ethereal_ir.to_string().as_str())?;

ethereal_ir.declare(context)?;
ethereal_ir.into_llvm(context)?;

Expand Down
Loading

0 comments on commit 6b4284c

Please sign in to comment.