From 233a26ed15c5a3ab59a130c326a05d3bb6d845b6 Mon Sep 17 00:00:00 2001 From: ksolana <110843012+ksolana@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:52:25 -0700 Subject: [PATCH] Allow passing opt level to the llvm optimizer The users of move compiler should not assume that the opt_level will always map to LLVMCodeGenOptLevel as the move-compiler may have its own set of optimizations --- language/solana/move-to-solana/src/lib.rs | 1 + language/solana/move-to-solana/src/options.rs | 4 +++ .../move-to-solana/src/stackless/llvm.rs | 26 +++++++++++++++---- .../tools/move-mv-llvm-compiler/src/cli.rs | 4 +++ .../tools/move-mv-llvm-compiler/src/main.rs | 17 +++++++----- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/language/solana/move-to-solana/src/lib.rs b/language/solana/move-to-solana/src/lib.rs index 96f9af2e84..dbebe65b6b 100644 --- a/language/solana/move-to-solana/src/lib.rs +++ b/language/solana/move-to-solana/src/lib.rs @@ -373,6 +373,7 @@ fn compile(global_env: &GlobalEnv, options: &Options) -> anyhow::Result<()> { tgt_platform.triple(), tgt_platform.llvm_cpu(), tgt_platform.llvm_features(), + &options.opt_level, ); let global_cx = GlobalContext::new(global_env, tgt_platform, &llmachine); let output_file_path = options.output.clone(); diff --git a/language/solana/move-to-solana/src/options.rs b/language/solana/move-to-solana/src/options.rs index c236adbad7..d7bff0e3de 100644 --- a/language/solana/move-to-solana/src/options.rs +++ b/language/solana/move-to-solana/src/options.rs @@ -75,6 +75,10 @@ pub struct Options { #[clap(long = "extension", default_value = "o")] pub output_file_extension: String, + /// Optimization Level [none, less, default, aggressive] + #[clap(long = "opt", default_value = "none")] + pub opt_level: String, + /// Output llvm bitcode in a human readable text format. #[clap(short = 'S')] pub llvm_ir: bool, diff --git a/language/solana/move-to-solana/src/stackless/llvm.rs b/language/solana/move-to-solana/src/stackless/llvm.rs index 78c8d61a0b..c9f4ab4a32 100644 --- a/language/solana/move-to-solana/src/stackless/llvm.rs +++ b/language/solana/move-to-solana/src/stackless/llvm.rs @@ -16,7 +16,7 @@ use libc::abort; use llvm_extra_sys::*; use llvm_sys::{core::*, prelude::*, target::*, target_machine::*, LLVMOpcode, LLVMUnnamedAddr}; -use log::debug; +use log::{debug, warn}; use move_core_types::u256; use num_traits::{PrimInt, ToPrimitive}; @@ -1512,10 +1512,26 @@ impl Target { } } - pub fn create_target_machine(&self, triple: &str, cpu: &str, features: &str) -> TargetMachine { + fn map_opt_level(opt_level: &str) -> LLVMCodeGenOptLevel { + match opt_level { + "none" => LLVMCodeGenOptLevel::LLVMCodeGenLevelNone, + "less" => LLVMCodeGenOptLevel::LLVMCodeGenLevelLess, + "default" => LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault, + "aggressive" => LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive, + _ => { + warn!("Invalid opt level: {opt_level}, defaulting to \'none\'"); + LLVMCodeGenOptLevel::LLVMCodeGenLevelNone + } + } + } + pub fn create_target_machine( + &self, + triple: &str, + cpu: &str, + features: &str, + opt_level: &str, + ) -> TargetMachine { unsafe { - // fixme some of these should be params - let level = LLVMCodeGenOptLevel::LLVMCodeGenLevelNone; let reloc = LLVMRelocMode::LLVMRelocPIC; let code_model = LLVMCodeModel::LLVMCodeModelDefault; @@ -1524,7 +1540,7 @@ impl Target { triple.cstr(), cpu.cstr(), features.cstr(), - level, + Self::map_opt_level(opt_level), reloc, code_model, ); diff --git a/language/tools/move-mv-llvm-compiler/src/cli.rs b/language/tools/move-mv-llvm-compiler/src/cli.rs index f14ed960cf..cde51f77e0 100644 --- a/language/tools/move-mv-llvm-compiler/src/cli.rs +++ b/language/tools/move-mv-llvm-compiler/src/cli.rs @@ -68,6 +68,10 @@ pub struct Args { #[clap(short = 'o', default_value = "-")] pub output_file_path: String, + /// Optimization Level [none, less, default, aggressive] + #[clap(long = "opt", default_value = "none")] + pub opt_level: String, + /// Output llvm bitcode in a human readable text format. #[clap(short = 'S')] pub llvm_ir: bool, diff --git a/language/tools/move-mv-llvm-compiler/src/main.rs b/language/tools/move-mv-llvm-compiler/src/main.rs index 6c3e0b9be8..1a2e2e6dd8 100644 --- a/language/tools/move-mv-llvm-compiler/src/main.rs +++ b/language/tools/move-mv-llvm-compiler/src/main.rs @@ -209,6 +209,15 @@ fn main() -> anyhow::Result<()> { stackless::{extensions::ModuleEnvExt, *}, }; + let options = MoveToSolanaOptions { + gen_dot_cfg: args.gen_dot_cfg.clone(), + dot_file_path: args.dot_file_path.clone(), + test_signers: args.test_signers.clone(), + debug: args.debug, + opt_level: args.opt_level.clone(), + ..MoveToSolanaOptions::default() + }; + let tgt_platform = TargetPlatform::Solana; tgt_platform.initialize_llvm(); let lltarget = Target::from_triple(tgt_platform.triple())?; @@ -216,6 +225,7 @@ fn main() -> anyhow::Result<()> { tgt_platform.triple(), tgt_platform.llvm_cpu(), tgt_platform.llvm_features(), + &options.opt_level, ); let global_cx = GlobalContext::new(&global_env, tgt_platform, &llmachine); @@ -241,13 +251,6 @@ fn main() -> anyhow::Result<()> { println!("{}", modname); } } - let options = MoveToSolanaOptions { - gen_dot_cfg: args.gen_dot_cfg.clone(), - dot_file_path: args.dot_file_path.clone(), - test_signers: args.test_signers.clone(), - debug: args.debug, - ..MoveToSolanaOptions::default() - }; let entry_llmod = global_cx.llvm_cx.create_module("solana_entrypoint"); let entrypoint_generator = EntrypointGenerator::new(&global_cx, &entry_llmod, &llmachine, &options);