Skip to content

Commit

Permalink
cli: Make --got-layout-file override the default GOT layout file loca…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
CohenArthur committed Jul 30, 2024
1 parent 63eca54 commit 21340e6
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 15 deletions.
14 changes: 9 additions & 5 deletions compiler/plc_driver/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use encoding_rs::Encoding;
use plc_diagnostics::diagnostics::{diagnostics_registry::DiagnosticsConfiguration, Diagnostic};
use std::{env, ffi::OsStr, num::ParseIntError, path::PathBuf};

use plc::{output::FormatOption, ConfigFormat, DebugLevel, ErrorFormat, Target, Threads};
use plc::output::FormatOption;
use plc::{ConfigFormat, DebugLevel, ErrorFormat, Target, Threads, DEFAULT_GOT_LAYOUT_FILE};

pub type ParameterError = clap::Error;

Expand Down Expand Up @@ -116,9 +117,11 @@ pub struct CompileParameters {
Save information about the generated custom GOT layout to the given file.
Format is detected by extension.
Supported formats : json, toml",
parse(try_from_str = validate_config)
default_value = DEFAULT_GOT_LAYOUT_FILE,
parse(try_from_str = validate_config),
requires = "online-change"
) ]
pub got_layout_file: Option<String>,
pub got_layout_file: String,

#[clap(
name = "optimization",
Expand Down Expand Up @@ -407,8 +410,9 @@ impl CompileParameters {
self.hardware_config.as_deref().and_then(get_config_format)
}

pub fn got_layout_format(&self) -> Option<ConfigFormat> {
self.got_layout_file.as_deref().and_then(get_config_format)
pub fn got_layout_format(&self) -> ConfigFormat {
// It is safe to unwrap here, since the provided argument to `--got-online-change` has been checked with `validate_config`
get_config_format(&self.got_layout_file).unwrap()
}

/// Returns the location where the build artifacts should be stored / output
Expand Down
10 changes: 5 additions & 5 deletions compiler/plc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use cli::{CompileParameters, ParameterError, SubCommands};
use pipelines::AnnotatedProject;
use plc::{
codegen::CodegenContext, linker::LinkerType, output::FormatOption, ConfigFormat, DebugLevel, ErrorFormat,
OnlineChange, OptimizationLevel, Target, Threads,
OnlineChange, OptimizationLevel, Target, Threads, DEFAULT_GOT_LAYOUT_FILE,
};

use plc_diagnostics::{diagnostician::Diagnostician, diagnostics::Diagnostic};
Expand Down Expand Up @@ -50,8 +50,8 @@ pub struct CompileOptions {
/// The name of the resulting compiled file
pub output: String,
pub output_format: FormatOption,
pub got_layout_file: Option<String>,
pub got_layout_format: Option<ConfigFormat>,
pub got_layout_file: String,
pub got_layout_format: ConfigFormat,
pub optimization: OptimizationLevel,
pub error_format: ErrorFormat,
pub debug_level: DebugLevel,
Expand All @@ -66,8 +66,8 @@ impl Default for CompileOptions {
build_location: None,
output: String::new(),
output_format: Default::default(),
got_layout_file: None,
got_layout_format: None,
got_layout_file: String::from(DEFAULT_GOT_LAYOUT_FILE),
got_layout_format: ConfigFormat::JSON,
optimization: OptimizationLevel::None,
error_format: ErrorFormat::None,
debug_level: DebugLevel::None,
Expand Down
2 changes: 1 addition & 1 deletion compiler/plc_driver/src/pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl<T: SourceContainer + Sync> AnnotatedProject<T> {
context,
compile_options.root.as_deref(),
&unit.file_name,
compile_options.got_layout_file.clone().zip(compile_options.got_layout_format),
(compile_options.got_layout_file.clone(), compile_options.got_layout_format),
compile_options.optimization,
compile_options.debug_level,
compile_options.online_change,
Expand Down
16 changes: 12 additions & 4 deletions src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub struct CodeGen<'ink> {
/// Whether we are generating a hot-reloadable binary or not
pub online_change: OnlineChange,

pub got_layout_file: Option<(String, ConfigFormat)>,
pub got_layout_file: (String, ConfigFormat),

pub module_location: String,
}
Expand All @@ -97,7 +97,7 @@ impl<'ink> CodeGen<'ink> {
context: &'ink CodegenContext,
root: Option<&Path>,
module_location: &str,
got_layout_file: Option<(String, ConfigFormat)>,
got_layout_file: (String, ConfigFormat),
optimization_level: OptimizationLevel,
debug_level: DebugLevel,
online_change: OnlineChange,
Expand Down Expand Up @@ -135,8 +135,16 @@ impl<'ink> CodeGen<'ink> {
)?;
index.merge(llvm_type_index);

let mut variable_generator =
VariableGenerator::new(&self.module, &llvm, global_index, annotations, &index, &mut self.debug);
let mut variable_generator = VariableGenerator::new(
&self.module,
&llvm,
global_index,
annotations,
&index,
&mut self.debug,
self.got_layout_file.clone(),
self.online_change,
);

//Generate global variables
let llvm_gv_index =
Expand Down
70 changes: 70 additions & 0 deletions src/codegen/generators/variable_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use crate::{
codegen::{debug::Debug, llvm_index::LlvmTypedIndex, llvm_typesystem::cast_if_needed},
index::{get_initializer_name, Index, PouIndexEntry, VariableIndexEntry},
resolver::{AnnotationMap, AstAnnotations, Dependency},
<<<<<<< HEAD
=======
ConfigFormat, OnlineChange,
>>>>>>> daa7fadae3 (cli: Make --got-layout-file override the default GOT layout file location)
};
use inkwell::{module::Module, values::GlobalValue};
use plc_ast::ast::LinkageType;
Expand All @@ -27,6 +31,11 @@ pub struct VariableGenerator<'ctx, 'b> {
annotations: &'b AstAnnotations,
types_index: &'b LlvmTypedIndex<'ctx>,
debug: &'b mut DebugBuilderEnum<'ctx>,
<<<<<<< HEAD
=======
got_layout_file: (String, ConfigFormat),
online_change: OnlineChange,
>>>>>>> daa7fadae3 (cli: Make --got-layout-file override the default GOT layout file location)
}

impl<'ctx, 'b> VariableGenerator<'ctx, 'b> {
Expand All @@ -37,8 +46,24 @@ impl<'ctx, 'b> VariableGenerator<'ctx, 'b> {
annotations: &'b AstAnnotations,
types_index: &'b LlvmTypedIndex<'ctx>,
debug: &'b mut DebugBuilderEnum<'ctx>,
<<<<<<< HEAD
) -> Self {
VariableGenerator { module, llvm, global_index, annotations, types_index, debug }
=======
got_layout_file: (String, ConfigFormat),
online_change: OnlineChange,
) -> Self {
VariableGenerator {
module,
llvm,
global_index,
annotations,
types_index,
debug,
got_layout_file,
online_change,
}
>>>>>>> daa7fadae3 (cli: Make --got-layout-file override the default GOT layout file location)
}

pub fn generate_global_variables(
Expand Down Expand Up @@ -100,6 +125,51 @@ impl<'ctx, 'b> VariableGenerator<'ctx, 'b> {
);
}

<<<<<<< HEAD
=======
if self.online_change == OnlineChange::Enabled {
let (location, format) = &self.got_layout_file;

let got_entries = read_got_layout(location.as_str(), *format)?;
let mut new_globals = Vec::new();
let mut new_got_entries = HashMap::new();
let mut new_got = HashMap::new();

for (name, _) in &globals {
if let Some(idx) = got_entries.get(&name.to_string()) {
new_got_entries.insert(name.to_string(), *idx);
new_got.insert(*idx, name.to_string());
} else {
new_globals.push(name.to_string());
}
}

// Put any globals that weren't there last time in any free space in the GOT.
let mut idx: u64 = 0;
for name in &new_globals {
while new_got.contains_key(&idx) {
idx += 1;
}
new_got_entries.insert(name.to_string(), idx);
new_got.insert(idx, name.to_string());
}

// Now we can write new_got_entries back out to a file.
write_got_layout(new_got_entries, location.as_str(), *format)?;

// Construct our GOT as a new global array. We initialise this array in the loader code.
let got_size = new_got.keys().max().map_or(0, |m| *m + 1);
let _got = self.llvm.create_global_variable(
self.module,
"__custom_got",
BasicTypeEnum::ArrayType(Llvm::get_array_type(
BasicTypeEnum::PointerType(self.llvm.context.i8_type().ptr_type(0.into())),
got_size.try_into().expect("the computed custom GOT size is too large"),
)),
);
}

>>>>>>> daa7fadae3 (cli: Make --got-layout-file override the default GOT layout file location)
Ok(index)
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ impl FromStr for ConfigFormat {
}
}

pub const DEFAULT_GOT_LAYOUT_FILE: &str = "online_change_got.json";

#[derive(Debug, Copy, Clone, PartialEq, Eq, ArgEnum, Serialize, Deserialize, Default)]
pub enum ErrorFormat {
#[default]
Expand Down

0 comments on commit 21340e6

Please sign in to comment.