From 364c4a70c9cff99f840f07400dced3e0d6a9dea9 Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Wed, 30 Oct 2024 16:04:04 +0100 Subject: [PATCH 1/9] Executing cargo +nightly fmt --- lib/bforest/src/lib.rs | 7 +- lib/bforest/src/map.rs | 3 +- lib/bforest/src/node.rs | 3 +- lib/bforest/src/node/tests.rs | 3 +- lib/bforest/src/path.rs | 5 +- lib/bforest/src/path/tests.rs | 6 +- lib/bforest/src/pool.rs | 3 +- lib/bforest/src/set.rs | 3 +- lib/bforest/src/set/tests.rs | 3 +- lib/list_pool/src/lib.rs | 1 + lib/stdx/src/ieee64/tests.rs | 3 +- lib/stdx/src/packed_option.rs | 3 +- melange/core/src/devices/vsource.rs | 4 +- melange/core/src/simulation/flags.rs | 3 +- melange/core/src/veriloga.rs | 11 +-- melange/core/src/veriloga/osdi_device.rs | 3 +- openvaf/basedb/tests/data_tests.rs | 4 +- openvaf/hir/src/body.rs | 32 ++++--- openvaf/hir/src/db.rs | 3 +- openvaf/hir/src/diagnostics.rs | 5 +- openvaf/hir/src/lib.rs | 28 +++--- openvaf/hir_def/src/nameres/diagnostics.rs | 3 +- openvaf/hir_def/tests/data_tests.rs | 3 +- openvaf/hir_lower/src/body.rs | 3 +- openvaf/hir_lower/src/expr.rs | 10 +- openvaf/hir_lower/src/lib.rs | 3 +- openvaf/hir_ty/src/diagnostics.rs | 1 - openvaf/linker/src/lib.rs | 8 +- openvaf/llvm/src/builder.rs | 2 +- openvaf/mir/src/dfg.rs | 7 +- openvaf/mir/src/dfg/postorder.rs | 3 +- openvaf/mir/src/dfg/tests.rs | 3 +- openvaf/mir/src/dfg/values.rs | 7 +- openvaf/mir/src/dominators.rs | 6 +- openvaf/mir/src/entities.rs | 1 + openvaf/mir/src/flowgraph/transversal.rs | 3 +- openvaf/mir/src/lib.rs | 5 +- openvaf/mir_autodiff/src/builder.rs | 2 +- openvaf/mir_autodiff/src/intern.rs | 3 +- openvaf/mir_build/src/ssa.rs | 13 ++- openvaf/mir_opt/src/global_value_numbering.rs | 7 +- openvaf/mir_opt/src/simplify_cfg.rs | 3 +- openvaf/mir_opt/src/split_tainted.rs | 4 +- openvaf/mir_reader/src/lexer.rs | 6 +- openvaf/mir_reader/src/lib.rs | 1 - openvaf/mir_reader/src/parser.rs | 8 +- openvaf/mir_reader/src/parser/tests.rs | 3 +- openvaf/openvaf-driver/src/crash_report.rs | 6 +- openvaf/openvaf-driver/src/main.rs | 5 +- openvaf/openvaf/src/lib.rs | 16 ++-- openvaf/osdi/build.rs | 2 +- openvaf/osdi/src/access.rs | 91 +++++++++--------- openvaf/osdi/src/compilation_unit.rs | 3 +- openvaf/osdi/src/inst_data.rs | 6 +- openvaf/osdi/src/lib.rs | 17 ++-- openvaf/osdi/src/load.rs | 49 +++++----- openvaf/osdi/src/metadata.rs | 34 +++---- openvaf/osdi/src/setup.rs | 1 - openvaf/preprocessor/src/processor.rs | 8 +- openvaf/sim_back/src/dae.rs | 6 +- openvaf/sim_back/src/dae/builder.rs | 94 ++++++++----------- openvaf/sim_back/src/lib.rs | 15 ++- openvaf/sim_back/src/node_collapse.rs | 6 +- openvaf/sim_back/src/util.rs | 10 +- openvaf/syntax/src/ast.rs | 3 +- openvaf/target/src/spec/apple_base.rs | 3 +- sourcegen/src/hir_builtins.rs | 3 +- verilogae/verilogae/src/compiler_db.rs | 3 +- verilogae/verilogae/src/lib.rs | 12 +-- verilogae/verilogae_ffi/src/lib.rs | 3 +- verilogae/verilogae_py/src/lib.rs | 3 +- verilogae/verilogae_py/src/load.rs | 4 +- verilogae/verilogae_py/src/model.rs | 14 +-- xtask/src/msvcrt.rs | 4 +- 74 files changed, 317 insertions(+), 358 deletions(-) diff --git a/lib/bforest/src/lib.rs b/lib/bforest/src/lib.rs index 20c04e0..ca2b9ec 100644 --- a/lib/bforest/src/lib.rs +++ b/lib/bforest/src/lib.rs @@ -16,11 +16,11 @@ #![deny(missing_docs, trivial_numeric_casts)] #![warn(unused_import_braces)] -use stdx::{impl_debug_display, impl_idx_from, packed_option}; - use core::borrow::BorrowMut; use core::cmp::Ordering; +use stdx::{impl_debug_display, impl_idx_from, packed_option}; + mod map; mod node; mod path; @@ -30,11 +30,10 @@ mod set; mod tests; pub use self::map::{Map, MapCursor, MapForest, MapIter}; -pub use self::set::{RevSetIter, Set, SetCursor, SetForest, SetIter}; - use self::node::NodeData; use self::path::Path; use self::pool::NodePool; +pub use self::set::{RevSetIter, Set, SetCursor, SetForest, SetIter}; /// The maximum branching factor of an inner node in a B+-tree. /// The minimum number of outgoing edges is `INNER_SIZE/2`. diff --git a/lib/bforest/src/map.rs b/lib/bforest/src/map.rs index 83cd229..a6af3bf 100644 --- a/lib/bforest/src/map.rs +++ b/lib/bforest/src/map.rs @@ -1,8 +1,9 @@ //! Forest of maps. +use core::marker::PhantomData; + use super::{Comparator, Forest, Node, NodeData, NodePool, Path, INNER_SIZE}; use crate::packed_option::PackedOption; -use core::marker::PhantomData; #[cfg(test)] mod tests; diff --git a/lib/bforest/src/node.rs b/lib/bforest/src/node.rs index ab8b4b9..12e590b 100644 --- a/lib/bforest/src/node.rs +++ b/lib/bforest/src/node.rs @@ -1,9 +1,10 @@ //! B+-tree nodes. -use super::{slice_insert, slice_shift, Forest, Node, SetValue, INNER_SIZE}; use core::borrow::{Borrow, BorrowMut}; use core::fmt; +use super::{slice_insert, slice_shift, Forest, Node, SetValue, INNER_SIZE}; + #[cfg(test)] mod tests; diff --git a/lib/bforest/src/node/tests.rs b/lib/bforest/src/node/tests.rs index 6f892d8..41ac094 100644 --- a/lib/bforest/src/node/tests.rs +++ b/lib/bforest/src/node/tests.rs @@ -1,6 +1,7 @@ -use super::*; use core::mem; +use super::*; + // Forest impl for a set implementation. struct TF(); diff --git a/lib/bforest/src/path.rs b/lib/bforest/src/path.rs index 820637f..83df518 100644 --- a/lib/bforest/src/path.rs +++ b/lib/bforest/src/path.rs @@ -3,12 +3,13 @@ #[cfg(test)] mod tests; -use super::node::Removed; -use super::{slice_insert, slice_shift, Comparator, Forest, Node, NodeData, NodePool, MAX_PATH}; use core::borrow::Borrow; use core::marker::PhantomData; use std::cmp::Ordering; +use super::node::Removed; +use super::{slice_insert, slice_shift, Comparator, Forest, Node, NodeData, NodePool, MAX_PATH}; + pub(super) struct Path { /// Number of path entries including the root and leaf nodes. size: usize, diff --git a/lib/bforest/src/path/tests.rs b/lib/bforest/src/path/tests.rs index 1d73b2c..dfa4f30 100644 --- a/lib/bforest/src/path/tests.rs +++ b/lib/bforest/src/path/tests.rs @@ -1,9 +1,9 @@ -use super::*; -use crate::{Forest, NodeData, NodePool}; - use std::cmp::Ordering; use std::fmt; +use super::*; +use crate::{Forest, NodeData, NodePool}; + impl Path { /// Check the internal consistency of this path. pub fn verify(&self, pool: &NodePool) { diff --git a/lib/bforest/src/pool.rs b/lib/bforest/src/pool.rs index e314147..5dd6ffe 100644 --- a/lib/bforest/src/pool.rs +++ b/lib/bforest/src/pool.rs @@ -2,11 +2,12 @@ // #[cfg(test)] // use super::Comparator; -use super::{Forest, Node, NodeData}; // #[cfg(test)] // use core::fmt; use core::ops::{Index, IndexMut}; +use super::{Forest, Node, NodeData}; + /// A pool of nodes, including a free list. pub(super) struct NodePool { nodes: Vec>, diff --git a/lib/bforest/src/set.rs b/lib/bforest/src/set.rs index 1604a11..bbcdb0f 100644 --- a/lib/bforest/src/set.rs +++ b/lib/bforest/src/set.rs @@ -2,9 +2,10 @@ #[cfg(test)] mod tests; +use core::marker::PhantomData; + use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE}; use crate::packed_option::PackedOption; -use core::marker::PhantomData; /// Tag type defining forest types for a set. struct SetTypes(PhantomData); diff --git a/lib/bforest/src/set/tests.rs b/lib/bforest/src/set/tests.rs index eafd34c..af65ea9 100644 --- a/lib/bforest/src/set/tests.rs +++ b/lib/bforest/src/set/tests.rs @@ -1,6 +1,7 @@ +use std::{fmt, mem}; + use super::*; use crate::NodeData; -use std::{fmt, mem}; impl<'a, K, C> SetCursor<'a, K, C> where diff --git a/lib/list_pool/src/lib.rs b/lib/list_pool/src/lib.rs index 6bc1fa3..19f9e6e 100644 --- a/lib/list_pool/src/lib.rs +++ b/lib/list_pool/src/lib.rs @@ -2,6 +2,7 @@ use std::marker::PhantomData; use std::mem; + use stdx::packed_option::ReservedValue; /// A small list of entity references allocated from a pool. diff --git a/lib/stdx/src/ieee64/tests.rs b/lib/stdx/src/ieee64/tests.rs index cc20042..24bef3b 100644 --- a/lib/stdx/src/ieee64/tests.rs +++ b/lib/stdx/src/ieee64/tests.rs @@ -1,8 +1,9 @@ -use super::*; use core::f64; use core::fmt::Display; use core::str::FromStr; +use super::*; + // Verify that `text` can be parsed as a `T` into a value that displays as `want`. fn parse_ok(text: &str, want: &str) where diff --git a/lib/stdx/src/packed_option.rs b/lib/stdx/src/packed_option.rs index 9cc87f2..811a521 100644 --- a/lib/stdx/src/packed_option.rs +++ b/lib/stdx/src/packed_option.rs @@ -7,8 +7,7 @@ //! This module provides a `PackedOption` for types that have a reserved value that can be used //! to represent `None`. -use core::fmt; -use core::mem; +use core::{fmt, mem}; /// Types that have a reserved value which can't be created any other way. pub trait ReservedValue { diff --git a/melange/core/src/devices/vsource.rs b/melange/core/src/devices/vsource.rs index f57a65c..2609312 100644 --- a/melange/core/src/devices/vsource.rs +++ b/melange/core/src/devices/vsource.rs @@ -1,5 +1,4 @@ use std::cell::Cell; - use std::ptr::NonNull; use std::rc::Rc; @@ -8,12 +7,11 @@ use num_complex::Complex64; use stdx::iter::zip; use typed_index_collections::TiSlice; +use super::{ModelImpl, ParamId, SimInfo}; use crate::circuit::Node; use crate::devices::{update_matrix_entry, DeviceImpl, DeviceParams, InstanceImpl, Type}; use crate::simulation::{MatrixEntryIter, SimBuilder}; -use super::{ModelImpl, ParamId, SimInfo}; - pub struct VoltageSrc; impl VoltageSrc { diff --git a/melange/core/src/simulation/flags.rs b/melange/core/src/simulation/flags.rs index 3a4a97b..a6b7a09 100644 --- a/melange/core/src/simulation/flags.rs +++ b/melange/core/src/simulation/flags.rs @@ -1,6 +1,7 @@ -use crate::veriloga::*; use bitflags::bitflags; +use crate::veriloga::*; + bitflags! { #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct EvalFlags: u32 { diff --git a/melange/core/src/veriloga.rs b/melange/core/src/veriloga.rs index 1faab25..e514df6 100644 --- a/melange/core/src/veriloga.rs +++ b/melange/core/src/veriloga.rs @@ -11,6 +11,11 @@ use log::{debug, error, info, warn}; use openvaf::{ AbsPathBuf, CompilationDestination, CompilationTermination, LintLevel, OptLevel, Target, }; +pub(crate) use osdi_0_4::{ + ANALYSIS_AC, ANALYSIS_DC, ANALYSIS_IC, ANALYSIS_NOISE, ANALYSIS_STATIC, ANALYSIS_TRAN, + CALC_NOISE, CALC_REACT_JACOBIAN, CALC_REACT_RESIDUAL, CALC_RESIST_JACOBIAN, + CALC_RESIST_RESIDUAL, +}; use crate::devices::DeviceImpl; use crate::veriloga::osdi_0_4::{ @@ -19,12 +24,6 @@ use crate::veriloga::osdi_0_4::{ }; use crate::veriloga::osdi_device::OsdiDevice; -pub(crate) use osdi_0_4::{ - ANALYSIS_AC, ANALYSIS_DC, ANALYSIS_IC, ANALYSIS_NOISE, ANALYSIS_STATIC, ANALYSIS_TRAN, - CALC_NOISE, CALC_REACT_JACOBIAN, CALC_REACT_RESIDUAL, CALC_RESIST_JACOBIAN, - CALC_RESIST_RESIDUAL, -}; - // autogenerated #[allow(warnings)] mod osdi_0_4; diff --git a/melange/core/src/veriloga/osdi_device.rs b/melange/core/src/veriloga/osdi_device.rs index 21819af..3337e78 100644 --- a/melange/core/src/veriloga/osdi_device.rs +++ b/melange/core/src/veriloga/osdi_device.rs @@ -1,4 +1,3 @@ -use anyhow::{bail, Result}; use std::alloc::{alloc_zeroed, handle_alloc_error, Layout}; use std::cell::Cell; use std::ffi::{c_void, CStr, CString}; @@ -6,6 +5,8 @@ use std::mem::{align_of, swap}; use std::os::raw::c_char; use std::rc::Rc; use std::{ptr, slice}; + +use anyhow::{bail, Result}; use stdx::format_to; use stdx::iter::zip; use typed_index_collections::TiSlice; diff --git a/openvaf/basedb/tests/data_tests.rs b/openvaf/basedb/tests/data_tests.rs index 0e3e6ab..196a1e2 100644 --- a/openvaf/basedb/tests/data_tests.rs +++ b/openvaf/basedb/tests/data_tests.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use basedb::diagnostics::{ConsoleSink, DiagnosticSink}; use basedb::{BaseDB, BaseDatabase, VfsPath, VfsStorage}; use codespan_reporting::term::termcolor::Buffer; @@ -8,8 +10,6 @@ use stdx::{ignore_dev_tests, ignore_never, is_va_file, openvaf_test_data, projec use syntax::{Parse, SourceFile}; use vfs::{AbsPathBuf, FileId, Vfs, VfsEntry}; -use std::path::Path; - #[salsa::database(BaseDatabase)] pub struct TestDataBase { storage: salsa::Storage, diff --git a/openvaf/hir/src/body.rs b/openvaf/hir/src/body.rs index 754fe5f..36f39a5 100644 --- a/openvaf/hir/src/body.rs +++ b/openvaf/hir/src/body.rs @@ -1,17 +1,18 @@ use std::sync::Arc; use hir_def::db::HirDefDB; +pub use hir_def::expr::Event; use hir_def::DefWithBodyId; +pub use hir_def::{/*expr::CaseCond,*/ BuiltIn, Case, ExprId, Literal, ParamSysFun, StmtId, Type,}; use hir_ty::db::HirTyDB; use hir_ty::inference; use hir_ty::types::{Signature, Ty}; - -pub use hir_def::expr::Event; -pub use hir_def::{/*expr::CaseCond,*/ BuiltIn, Case, ExprId, Literal, ParamSysFun, StmtId, Type}; pub use syntax::ast::{BinaryOp, UnaryOp}; -use crate::{Branch, CompilationDB, Node}; -use crate::{BranchWrite, Function, FunctionArg, NatureAttribute, Parameter, Variable}; +use crate::{ + Branch, BranchWrite, CompilationDB, Function, FunctionArg, NatureAttribute, Node, Parameter, + Variable, +}; #[derive(Debug, Clone)] pub struct Body { @@ -90,8 +91,8 @@ impl<'a> BodyRef<'a> { match &self.body.exprs[expr1] { hir_def::Expr::Literal(lit) => match &lit { Literal::Int(ii) => Some(*ii), // Int literal - _ => None, // other literals - } + _ => None, // other literals + }, _ => None, // not a literal } } @@ -99,16 +100,19 @@ impl<'a> BodyRef<'a> { // AB: get integer literal with optional negative sign pub fn as_literalsignedint(&self, &expr1: &ExprId) -> Option { match &self.body.exprs[expr1] { - hir_def::Expr::Literal(lit) => match &lit { // Literal + hir_def::Expr::Literal(lit) => match &lit { + // Literal Literal::Int(ii) => Some(*ii), // Int literal - _ => None, // other literals - } - hir_def::Expr::UnaryOp { expr, op } => { // UnaryOp + _ => None, // other literals + }, + hir_def::Expr::UnaryOp { expr, op } => { + // UnaryOp match op { - UnaryOp::Neg => match self.as_literalint(expr) { // Neg + UnaryOp::Neg => match self.as_literalint(expr) { + // Neg Some(ii) => Some(-ii), // Neg Int literal - _ => None, // Neg anything else - } + _ => None, // Neg anything else + }, _ => None, // Other UnaryOp } } diff --git a/openvaf/hir/src/db.rs b/openvaf/hir/src/db.rs index 8b91cdb..e92a237 100644 --- a/openvaf/hir/src/db.rs +++ b/openvaf/hir/src/db.rs @@ -6,8 +6,7 @@ use std::{fs, io}; use anyhow::{bail, Result}; use basedb::lints::{Lint, LintLevel}; -use basedb::AbsPathBuf; -use basedb::{BaseDB, BaseDatabase, FileId, Vfs, VfsPath, VfsStorage, STANDARD_FLAGS}; +use basedb::{AbsPathBuf, BaseDB, BaseDatabase, FileId, Vfs, VfsPath, VfsStorage, STANDARD_FLAGS}; use hir_def::db::{HirDefDB, HirDefDatabase, InternDatabase}; use hir_ty::db::HirTyDatabase; use parking_lot::RwLock; diff --git a/openvaf/hir/src/diagnostics.rs b/openvaf/hir/src/diagnostics.rs index bc0f1ef..29ce7c0 100644 --- a/openvaf/hir/src/diagnostics.rs +++ b/openvaf/hir/src/diagnostics.rs @@ -1,4 +1,6 @@ +pub use basedb::diagnostics::*; use basedb::AstIdMap; +pub use basedb::{BaseDB, FileId}; use hir_def::db::HirDefDB; use hir_def::nameres::diagnostics::DefDiagnosticWrapped; use hir_def::nameres::{DefMap, LocalScopeId, ScopeDefItem, ScopeOrigin}; @@ -11,9 +13,6 @@ use hir_ty::validation::{ use syntax::sourcemap::SourceMap; use syntax::{Parse, SourceFile}; -pub use basedb::diagnostics::*; -pub use basedb::{BaseDB, FileId}; - use crate::{CompilationDB, HirDatabase}; pub(crate) fn collect(db: &CompilationDB, root_file: FileId, sink: &mut impl DiagnosticSink) { diff --git a/openvaf/hir/src/lib.rs b/openvaf/hir/src/lib.rs index f7c376a..b346e88 100644 --- a/openvaf/hir/src/lib.rs +++ b/openvaf/hir/src/lib.rs @@ -13,32 +13,26 @@ use std::sync::Arc; use basedb::diagnostics::sink::Buffer; use basedb::diagnostics::ConsoleSink; -use basedb::BaseDB; -use basedb::FileId; +pub use basedb::diagnostics::DiagnosticSink; +use basedb::{BaseDB, FileId}; +pub use hir_def::body::{ConstraintValue, ParamConstraint}; use hir_def::db::HirDefDB; +pub use hir_def::expr::CaseCond; +pub use hir_def::nameres::diagnostics::PathResolveError; use hir_def::nameres::{DefMap, LocalScopeId, ScopeDefItem}; -use hir_def::DefWithBodyId; -use hir_def::DisciplineId; -use hir_def::LocalFunctionArgId; -use hir_def::NatureAttrId; -use hir_def::NatureId; use hir_def::{ - AliasParamId, BlockId, BlockLoc, BranchId, FunctionId, Lookup, ModuleId, ModuleLoc, NodeId, - ParamId, VarId, + AliasParamId, BlockId, BlockLoc, BranchId, DefWithBodyId, DisciplineId, FunctionId, + LocalFunctionArgId, Lookup, ModuleId, ModuleLoc, NatureAttrId, NatureId, NodeId, ParamId, + VarId, }; +pub use hir_def::{BuiltIn, Case, Literal, ParamSysFun, Path, Type}; +pub use hir_ty::builtin; use hir_ty::db::HirTyDB as HirDatabase; use hir_ty::inference; +pub use rec_declarations::RecDeclarations; use salsa::InternKey; use smol_str::SmolStr; use syntax::ast; - -pub use basedb::diagnostics::DiagnosticSink; -pub use hir_def::body::{ConstraintValue, ParamConstraint}; -pub use hir_def::expr::CaseCond; -pub use hir_def::nameres::diagnostics::PathResolveError; -pub use hir_def::{BuiltIn, Case, Literal, ParamSysFun, Path, Type}; -pub use hir_ty::builtin; -pub use rec_declarations::RecDeclarations; pub use syntax::name::Name; pub use crate::attributes::AstCache; diff --git a/openvaf/hir_def/src/nameres/diagnostics.rs b/openvaf/hir_def/src/nameres/diagnostics.rs index 17cf26e..7001575 100644 --- a/openvaf/hir_def/src/nameres/diagnostics.rs +++ b/openvaf/hir_def/src/nameres/diagnostics.rs @@ -7,9 +7,8 @@ use syntax::name::Name; use syntax::sourcemap::{FileSpan, SourceMap}; use syntax::{Parse, SourceFile}; -use crate::db::HirDefDB; - use super::{ResolvedPath, ScopeDefItem}; +use crate::db::HirDefDB; #[derive(Debug, Clone, PartialEq, Eq)] pub enum PathResolveError { diff --git a/openvaf/hir_def/tests/data_tests.rs b/openvaf/hir_def/tests/data_tests.rs index 38775e1..1946e71 100644 --- a/openvaf/hir_def/tests/data_tests.rs +++ b/openvaf/hir_def/tests/data_tests.rs @@ -9,8 +9,7 @@ use hir_def::nameres::{DefMap, LocalScopeId, ScopeDefItem, ScopeOrigin}; use hir_def::DefWithBodyId; use mini_harness::{harness, Result}; use parking_lot::RwLock; -use stdx::Upcast; -use stdx::{ignore_dev_tests, ignore_never, is_va_file, openvaf_test_data, project_root}; +use stdx::{ignore_dev_tests, ignore_never, is_va_file, openvaf_test_data, project_root, Upcast}; #[salsa::database(BaseDatabase, InternDatabase, HirDefDatabase)] pub struct TestDataBase { diff --git a/openvaf/hir_lower/src/body.rs b/openvaf/hir_lower/src/body.rs index 7510a45..6a5b04e 100644 --- a/openvaf/hir_lower/src/body.rs +++ b/openvaf/hir_lower/src/body.rs @@ -1,5 +1,4 @@ -use hir::Node; -use hir::{BodyRef, ExprId}; +use hir::{BodyRef, ExprId, Node}; use mir::builder::InstBuilder; use mir::{Block, Value}; use stdx::iter::zip; diff --git a/openvaf/hir_lower/src/expr.rs b/openvaf/hir_lower/src/expr.rs index 73d493f..14a797b 100644 --- a/openvaf/hir_lower/src/expr.rs +++ b/openvaf/hir_lower/src/expr.rs @@ -564,10 +564,10 @@ impl BodyLoweringCtx<'_, '_, '_> { CurrentKind::Port(self.body.into_port_flow(args[0])) )) }; - // AB: Do not divide flow probe. - // Flow unknowns correspond to the flow of a single parallel instance. - // HIR equation describes a single parallel instance. - // Handle $mfactor at a lower level. + // AB: Do not divide flow probe. + // Flow unknowns correspond to the flow of a single parallel instance. + // HIR equation describes a single parallel instance. + // Handle $mfactor at a lower level. // let mfactor = self.ctx.use_param(ParamKind::ParamSysFun(ParamSysFun::mfactor)); // return self.ctx.ins().fdiv(res, mfactor); return res; @@ -660,7 +660,7 @@ impl BodyLoweringCtx<'_, '_, '_> { } BuiltIn::discontinuity => { // AB: Negative literals are represented as UnaryOp::Neg(Literal) - // We have a function for that now. + // We have a function for that now. if self.ctx.inside_lim && Some(-1) == self.body.as_literalsignedint(&args[0]) { self.ctx.call(CallBackKind::LimDiscontinuity, &[]); } else { diff --git a/openvaf/hir_lower/src/lib.rs b/openvaf/hir_lower/src/lib.rs index ed5e7f5..9866d92 100644 --- a/openvaf/hir_lower/src/lib.rs +++ b/openvaf/hir_lower/src/lib.rs @@ -2,6 +2,7 @@ use std::iter::FilterMap; use ahash::{AHashMap, AHashSet}; use bitset::HybridBitSet; +pub use callbacks::{CallBackKind, NoiseTable, ParamInfoKind}; use hir::{ Branch, BranchWrite, CompilationDB, Module, Node, ParamSysFun, Parameter, Type, Variable, }; @@ -15,8 +16,6 @@ use stdx::{impl_debug_display, impl_idx_from}; use typed_index_collections::TiVec; use typed_indexmap::{map, TiMap, TiSet}; -pub use callbacks::{CallBackKind, NoiseTable, ParamInfoKind}; - use crate::body::BodyLoweringCtx; use crate::ctx::LoweringCtx; diff --git a/openvaf/hir_ty/src/diagnostics.rs b/openvaf/hir_ty/src/diagnostics.rs index b8ea3ea..29f2959 100644 --- a/openvaf/hir_ty/src/diagnostics.rs +++ b/openvaf/hir_ty/src/diagnostics.rs @@ -8,7 +8,6 @@ use basedb::lints::builtin::non_standard_code; use basedb::lints::{Lint, LintSrc}; use basedb::{BaseDB, FileId}; use hir_def::body::BodySourceMap; - use hir_def::{ExprId, FunctionId, Lookup, Type}; use stdx::iter::zip; use stdx::pretty::List; diff --git a/openvaf/linker/src/lib.rs b/openvaf/linker/src/lib.rs index 29c71eb..3e17b51 100644 --- a/openvaf/linker/src/lib.rs +++ b/openvaf/linker/src/lib.rs @@ -1,7 +1,3 @@ -use anyhow::{bail, Context, Result}; -use camino::{Utf8Path, Utf8PathBuf}; -use cc::windows_registry; - use std::ffi::{OsStr, OsString}; use std::fs::{remove_file, File}; use std::io::Write; @@ -9,6 +5,10 @@ use std::mem::take; use std::path::{Path, PathBuf}; use std::process::{Output, Stdio}; use std::{ascii, env, io}; + +use anyhow::{bail, Context, Result}; +use camino::{Utf8Path, Utf8PathBuf}; +use cc::windows_registry; use target::spec::{LinkerFlavor, Target}; pub fn link( diff --git a/openvaf/llvm/src/builder.rs b/openvaf/llvm/src/builder.rs index 4c162d9..91544bb 100644 --- a/openvaf/llvm/src/builder.rs +++ b/openvaf/llvm/src/builder.rs @@ -1,7 +1,7 @@ use ::libc::{c_char, c_uint}; +pub use LLVMBuildInBoundsGEP2 as LLVMBuildGEP2; use crate::{BasicBlock, Bool, Builder, Context, IntPredicate, RealPredicate, Type, Value}; -pub use LLVMBuildInBoundsGEP2 as LLVMBuildGEP2; // Core->Instruction Builders extern "C" { diff --git a/openvaf/mir/src/dfg.rs b/openvaf/mir/src/dfg.rs index f0074f2..3fee274 100644 --- a/openvaf/mir/src/dfg.rs +++ b/openvaf/mir/src/dfg.rs @@ -5,17 +5,16 @@ use typed_index_collections::TiVec; use crate::builder::ReplaceBuilder; use crate::dfg::instructions::DfgInsructions; +pub use crate::dfg::postorder::{Postorder, PostorderParts}; +pub use crate::dfg::uses::{DoubleEndedUseIter, InstUseIter, UseCursor, UseIter}; use crate::dfg::values::consts::{FALSE, TRUE}; use crate::dfg::values::ValueDataType; +pub use crate::dfg::values::{consts, Const, DfgValues, ValueDef}; use crate::entities::{Inst, Param, Tag, Value}; use crate::instructions::PhiForest; use crate::write::write_operands; use crate::{Block, FuncRef, FunctionSignature, Ieee64, InstructionData, Use, ValueList}; -pub use crate::dfg::postorder::{Postorder, PostorderParts}; -pub use crate::dfg::uses::{DoubleEndedUseIter, InstUseIter, UseCursor, UseIter}; -pub use crate::dfg::values::{consts, Const, DfgValues, ValueDef}; - #[cfg(test)] mod tests; diff --git a/openvaf/mir/src/dfg/postorder.rs b/openvaf/mir/src/dfg/postorder.rs index 2d7cfdc..139095a 100644 --- a/openvaf/mir/src/dfg/postorder.rs +++ b/openvaf/mir/src/dfg/postorder.rs @@ -1,6 +1,7 @@ -use crate::{DataFlowGraph, Inst, InstUseIter, Use, Value}; use bitset::BitSet; +use crate::{DataFlowGraph, Inst, InstUseIter, Use, Value}; + pub type PostorderParts<'a> = (BitSet, Vec<(Inst, InstUseIter<'a>)>); /// Postorder traversal of a data flow graph diff --git a/openvaf/mir/src/dfg/tests.rs b/openvaf/mir/src/dfg/tests.rs index 63bc72d..bc669f0 100644 --- a/openvaf/mir/src/dfg/tests.rs +++ b/openvaf/mir/src/dfg/tests.rs @@ -1,10 +1,9 @@ use expect_test::expect; +use super::*; use crate::instructions::{Opcode, PhiMap, PhiNode}; use crate::{Block, F_ZERO}; -use super::*; - #[test] fn make_inst() { let mut dfg = DataFlowGraph::new(); diff --git a/openvaf/mir/src/dfg/values.rs b/openvaf/mir/src/dfg/values.rs index 02bdaba..0a06b81 100644 --- a/openvaf/mir/src/dfg/values.rs +++ b/openvaf/mir/src/dfg/values.rs @@ -1,6 +1,7 @@ use std::borrow::Borrow; use ahash::AHashMap; +use consts::*; use lasso::Spur; use stdx::packed_option::PackedOption; use typed_index_collections::TiVec; @@ -9,8 +10,6 @@ use crate::dfg::uses::UseData; use crate::entities::{Param, Tag}; use crate::{DataFlowGraph, Ieee64, Inst, Use, Value}; -use consts::*; - macro_rules! consts { ( $(pub const $name: ident: $ty: ident = $val: expr;)* @@ -53,9 +52,7 @@ macro_rules! consts { pub mod consts { use std::f64::consts::{LN_2, LOG10_E}; - use super::DfgValues; - use super::Value; - use super::ValueDataType; + use super::{DfgValues, Value, ValueDataType}; consts! { // Place holder for unused values that must remain (in phis) diff --git a/openvaf/mir/src/dominators.rs b/openvaf/mir/src/dominators.rs index d7f56f7..e84c34c 100644 --- a/openvaf/mir/src/dominators.rs +++ b/openvaf/mir/src/dominators.rs @@ -2,13 +2,13 @@ use std::cmp::Ordering; use std::fs::File; use std::path::Path; -use crate::flowgraph::Successors; -use crate::ControlFlowGraph; -use crate::{Block, Function}; use bitset::SparseBitMatrix; use stdx::packed_option::PackedOption; use typed_index_collections::{TiSlice, TiVec}; +use crate::flowgraph::Successors; +use crate::{Block, ControlFlowGraph, Function}; + /* AB: unused trait CfgREVERSE { type Successors; diff --git a/openvaf/mir/src/entities.rs b/openvaf/mir/src/entities.rs index 21aa8be..77f7279 100644 --- a/openvaf/mir/src/entities.rs +++ b/openvaf/mir/src/entities.rs @@ -21,6 +21,7 @@ use core::u32; use std::fmt; + use stdx::{impl_debug_display, impl_idx_from}; // impl From for Block {} diff --git a/openvaf/mir/src/flowgraph/transversal.rs b/openvaf/mir/src/flowgraph/transversal.rs index 7da2adf..5a73c8a 100644 --- a/openvaf/mir/src/flowgraph/transversal.rs +++ b/openvaf/mir/src/flowgraph/transversal.rs @@ -1,8 +1,7 @@ -use crate::Block; use bitset::BitSet; use crate::flowgraph::Successors; -use crate::ControlFlowGraph; +use crate::{Block, ControlFlowGraph}; /// Postorder traversal of a graph. /// diff --git a/openvaf/mir/src/lib.rs b/openvaf/mir/src/lib.rs index 8f5a635..ecd7cb0 100644 --- a/openvaf/mir/src/lib.rs +++ b/openvaf/mir/src/lib.rs @@ -34,10 +34,12 @@ pub mod cursor; pub mod flowgraph; pub mod write; +use core::fmt; + use ahash::AHashMap; use bitset::HybridBitSet; -use core::fmt; pub use lasso::{Interner, Spur}; +pub use stdx::Ieee64; use stdx::{impl_debug, impl_display, impl_idx_from}; use typed_index_collections::TiVec; use typed_indexmap::TiSet; @@ -55,7 +57,6 @@ pub use crate::instructions::{ }; pub use crate::layout::{InstCursor, InstIter, Layout}; use crate::write::DummyResolver; -pub use stdx::Ieee64; #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct FunctionSignature { diff --git a/openvaf/mir_autodiff/src/builder.rs b/openvaf/mir_autodiff/src/builder.rs index 7e234ca..82593b6 100644 --- a/openvaf/mir_autodiff/src/builder.rs +++ b/openvaf/mir_autodiff/src/builder.rs @@ -499,7 +499,7 @@ impl<'a, 'u> DerivativeBuilder<'a, 'u> { // Technically not required but makes code look nicer.. // exp(x) -> exp(x) -// Opcode::Exp => res, + // Opcode::Exp => res, Opcode::Exp => self.ins().exp(arg0), // hypot(x,y) -> (x' + y')/2hypot(x,y) diff --git a/openvaf/mir_autodiff/src/intern.rs b/openvaf/mir_autodiff/src/intern.rs index 010ac44..24537cf 100644 --- a/openvaf/mir_autodiff/src/intern.rs +++ b/openvaf/mir_autodiff/src/intern.rs @@ -4,8 +4,7 @@ use std::mem::take; use ahash::AHashMap; use bitset::HybridBitSet; -use mir::Unknown; -use mir::{FuncRef, KnownDerivatives, Value}; +use mir::{FuncRef, KnownDerivatives, Unknown, Value}; use stdx::{impl_debug, impl_idx_from}; use typed_indexmap::TiSet; diff --git a/openvaf/mir_build/src/ssa.rs b/openvaf/mir_build/src/ssa.rs index 48a3267..ce76833 100644 --- a/openvaf/mir_build/src/ssa.rs +++ b/openvaf/mir_build/src/ssa.rs @@ -13,14 +13,13 @@ use bforest::Map; use bitset::HybridBitSet; use mir::builder::InstBuilderBase; use mir::cursor::{Cursor, FuncCursor}; +pub(crate) use mir::ControlFlowGraph as CompleteCfg; use mir::{Block, Function, PhiNode, Value, ValueList, GRAVESTONE}; use smallvec::SmallVec; use stdx::iter::zip; use stdx::packed_option::PackedOption; use typed_index_collections::TiVec; -pub(crate) use mir::ControlFlowGraph as CompleteCfg; - use crate::Place; pub(crate) trait ControlFlowGraph { @@ -39,8 +38,14 @@ pub(crate) trait ControlFlowGraph { } impl<'c> ControlFlowGraph for &'c CompleteCfg { - type Predecessors<'a> = mir::flowgraph::PredecessorIter<'a> where 'c: 'a; - type PredecessorsRev<'a> = mir::flowgraph::PredecessorRevIter<'a> where 'c: 'a; + type Predecessors<'a> + = mir::flowgraph::PredecessorIter<'a> + where + 'c: 'a; + type PredecessorsRev<'a> + = mir::flowgraph::PredecessorRevIter<'a> + where + 'c: 'a; const NEEDS_TAG: bool = false; fn predecessors(&self, bb: Block) -> Self::Predecessors<'_> { diff --git a/openvaf/mir_opt/src/global_value_numbering.rs b/openvaf/mir_opt/src/global_value_numbering.rs index d5af151..f96fd9e 100644 --- a/openvaf/mir_opt/src/global_value_numbering.rs +++ b/openvaf/mir_opt/src/global_value_numbering.rs @@ -1,14 +1,15 @@ use std::cmp::Ordering; use std::hash::{BuildHasher, Hash, Hasher}; - use std::mem::{swap, ManuallyDrop}; use std::ops::{Index, IndexMut}; use ahash::RandomState; use bitset::{BitSet, HybridBitSet}; use hashbrown::raw::RawTable; -use mir::DominatorTree; -use mir::{Block, FuncRef, Function, Inst, InstructionData, Opcode, Value, ValueDef, ValueList}; +use mir::{ + Block, DominatorTree, FuncRef, Function, Inst, InstructionData, Opcode, Value, ValueDef, + ValueList, +}; use stdx::packed_option::PackedOption; use stdx::{impl_idx_from, impl_idx_math}; use typed_index_collections::TiVec; diff --git a/openvaf/mir_opt/src/simplify_cfg.rs b/openvaf/mir_opt/src/simplify_cfg.rs index d9f5b3b..8225e1c 100644 --- a/openvaf/mir_opt/src/simplify_cfg.rs +++ b/openvaf/mir_opt/src/simplify_cfg.rs @@ -2,7 +2,7 @@ use std::iter::repeat; use bitset::BitSet; -use mir::{Block, ControlFlowGraph, Function, InstructionData, /* Value,*/ ValueDef, FALSE, TRUE}; +use mir::{Block, ControlFlowGraph, Function, InstructionData, /* Value,*/ ValueDef, FALSE, TRUE,}; #[cfg(test)] mod tests; @@ -654,4 +654,3 @@ impl + Clone> PartialEq for ResolvedPhi { } impl + Clone> Eq for ResolvedPhi {} */ - diff --git a/openvaf/mir_opt/src/split_tainted.rs b/openvaf/mir_opt/src/split_tainted.rs index 76977bf..dd15ea2 100644 --- a/openvaf/mir_opt/src/split_tainted.rs +++ b/openvaf/mir_opt/src/split_tainted.rs @@ -1,7 +1,5 @@ use bitset::{BitSet, HybridBitSet, SparseBitMatrix}; -use mir::{Block, ControlFlowGraph, Function, Inst, InstructionData, Value}; - -use mir::DominatorTree; +use mir::{Block, ControlFlowGraph, DominatorTree, Function, Inst, InstructionData, Value}; pub fn propagate_taint( func: &Function, diff --git a/openvaf/mir_reader/src/lexer.rs b/openvaf/mir_reader/src/lexer.rs index cf80326..c86da02 100644 --- a/openvaf/mir_reader/src/lexer.rs +++ b/openvaf/mir_reader/src/lexer.rs @@ -1,9 +1,11 @@ //! Lexical analysis for .clif files. -use crate::error::Location; -use mir::{Block, Value}; use std::str::CharIndices; +use mir::{Block, Value}; + +use crate::error::Location; + #[cfg(test)] mod tests; diff --git a/openvaf/mir_reader/src/lib.rs b/openvaf/mir_reader/src/lib.rs index 8216623..e6e3e1a 100644 --- a/openvaf/mir_reader/src/lib.rs +++ b/openvaf/mir_reader/src/lib.rs @@ -4,5 +4,4 @@ mod parser; pub use error::{ParseError, ParseResult}; pub use lexer::LexError; - pub use parser::{parse_function, parse_functions}; diff --git a/openvaf/mir_reader/src/parser.rs b/openvaf/mir_reader/src/parser.rs index 741d74c..a7552db 100644 --- a/openvaf/mir_reader/src/parser.rs +++ b/openvaf/mir_reader/src/parser.rs @@ -3,10 +3,6 @@ use std::fmt::{self, Display, Formatter}; use std::ops::{Deref, DerefMut}; -use crate::error::{Location, ParseResult}; -use crate::lexer::{LexError, Lexer, LocatedError, LocatedToken, Token}; -use crate::ParseError; - use bforest::Map; use lasso::{Rodeo, Spur}; use mir::{ @@ -14,6 +10,10 @@ use mir::{ Opcode, Param, PhiNode, SourceLoc, Value, ValueList, ValueListPool, }; +use crate::error::{Location, ParseResult}; +use crate::lexer::{LexError, Lexer, LocatedError, LocatedToken, Token}; +use crate::ParseError; + #[cfg(test)] mod tests; diff --git a/openvaf/mir_reader/src/parser/tests.rs b/openvaf/mir_reader/src/parser/tests.rs index ac4cc08..9edb26f 100644 --- a/openvaf/mir_reader/src/parser/tests.rs +++ b/openvaf/mir_reader/src/parser/tests.rs @@ -1,6 +1,7 @@ -use super::*; use expect_test::expect; +use super::*; + #[test] fn number_of_blocks() { let ParseError { location, message, is_warning } = Parser::new( diff --git a/openvaf/openvaf-driver/src/crash_report.rs b/openvaf/openvaf-driver/src/crash_report.rs index e553090..8fa5198 100644 --- a/openvaf/openvaf-driver/src/crash_report.rs +++ b/openvaf/openvaf-driver/src/crash_report.rs @@ -4,9 +4,11 @@ use std::error::Error; use std::fmt::Write as FmtWrite; +use std::fs::File; +use std::io::Write; use std::panic::PanicInfo; -use std::{env, fs::File, io::Write, path::Path, path::PathBuf}; -use std::{io, mem, panic}; +use std::path::{Path, PathBuf}; +use std::{env, io, mem, panic}; use backtrace::Backtrace; use backtrace_ext::short_frames_strict; diff --git a/openvaf/openvaf-driver/src/main.rs b/openvaf/openvaf-driver/src/main.rs index 15dee7a..5c6fbc9 100644 --- a/openvaf/openvaf-driver/src/main.rs +++ b/openvaf/openvaf-driver/src/main.rs @@ -5,11 +5,10 @@ use std::sync::Mutex; use anyhow::{bail, Result}; use camino::Utf8PathBuf; use clap::ArgMatches; -use mimalloc::MiMalloc; -use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; - use cli_def::{main_command, INPUT}; +use mimalloc::MiMalloc; use openvaf::{compile, expand, CompilationDestination, CompilationTermination, Opts}; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use crate::cli_def::{DUMP_JSON, PRINT_EXPANSION}; use crate::cli_process::matches_to_opts; diff --git a/openvaf/openvaf/src/lib.rs b/openvaf/openvaf/src/lib.rs index 1dbd6f3..2f85e3d 100644 --- a/openvaf/openvaf/src/lib.rs +++ b/openvaf/openvaf/src/lib.rs @@ -2,23 +2,20 @@ use std::fs::{create_dir_all, remove_file}; use std::io::Write; use std::time::Instant; -use anyhow::Context; -use anyhow::Result; +use anyhow::{Context, Result}; use basedb::diagnostics::{ConsoleSink, DiagnosticSink}; +pub use basedb::lints::{builtin as builtin_lints, LintLevel}; use basedb::BaseDB; use camino::Utf8PathBuf; use hir::CompilationDB; use linker::link; -use mir_llvm::LLVMBackend; -use sim_back::collect_modules; -use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; - -pub use basedb::lints::builtin as builtin_lints; -pub use basedb::lints::LintLevel; pub use llvm::OptLevel; +use mir_llvm::LLVMBackend; pub use paths::AbsPathBuf; +use sim_back::collect_modules; pub use target::host_triple; pub use target::spec::{get_target_names, Target}; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; mod cache; @@ -126,12 +123,11 @@ pub fn expand(opts: &Opts) -> Result { } else { print!("{}", &text[span.range]) } - }, + } _ => { // Add a space after each token print!("{} ", &text[span.range]) } - }; } println!(); diff --git a/openvaf/osdi/build.rs b/openvaf/osdi/build.rs index 39210cb..0c609a5 100644 --- a/openvaf/osdi/build.rs +++ b/openvaf/osdi/build.rs @@ -2,8 +2,8 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::fmt::Display; use std::path::Path; -use target::spec::get_targets; +use target::spec::get_targets; use xshell::{cmd, Shell}; /// Reads an environment variable and adds it to dependencies. diff --git a/openvaf/osdi/src/access.rs b/openvaf/osdi/src/access.rs index 718a628..9efecfb 100644 --- a/openvaf/osdi/src/access.rs +++ b/openvaf/osdi/src/access.rs @@ -1,8 +1,8 @@ use llvm::IntPredicate::IntNE; use llvm::{ LLVMAddCase, LLVMAppendBasicBlockInContext, LLVMBuildAnd, LLVMBuildBr, LLVMBuildCondBr, - LLVMBuildICmp, LLVMBuildRet, LLVMBuildSwitch, LLVMCreateBuilderInContext, LLVMDisposeBuilder, - LLVMGetParam, LLVMPositionBuilderAtEnd, LLVMBuildSelect, UNNAMED, + LLVMBuildICmp, LLVMBuildRet, LLVMBuildSelect, LLVMBuildSwitch, LLVMCreateBuilderInContext, + LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, UNNAMED, }; use crate::compilation_unit::OsdiCompilationUnit; @@ -31,13 +31,13 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llbuilder = LLVMCreateBuilderInContext(cx.llcx); LLVMPositionBuilderAtEnd(llbuilder, entry); - + // get params let inst = LLVMGetParam(llfunc, 0); let model = LLVMGetParam(llfunc, 1); let param_id = LLVMGetParam(llfunc, 2); let flags = LLVMGetParam(llfunc, 3); - + // constants let access_flag_instance = cx.const_unsigned_int(ACCESS_FLAG_INSTANCE); let access_flag_set = cx.const_unsigned_int(ACCESS_FLAG_SET); @@ -55,7 +55,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let flags_and_set = LLVMBuildAnd(llbuilder, flags, access_flag_set, UNNAMED); let write_flag_set = LLVMBuildICmp(llbuilder, IntNE, flags_and_set, zero, UNNAMED); - // build if block, true block is for instance flag set, false block is for instance flag not set + // build if block, true block is for instance flag set, false block is for instance flag not set LLVMBuildCondBr(llbuilder, instance_flag_set, inst_bb, model_bb); // @@ -80,16 +80,16 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let case = cx.const_unsigned_int(param_idx as u32); LLVMAddCase(switch_inst, case, bb); - // build code for retrieving pointer to parameter storage of + // build code for retrieving pointer to parameter storage of // param_idx-th instance parameter in instance structure let (ptr, _) = inst_data.nth_param_ptr(param_idx as u32, inst, llbuilder); // set the param_given flag if write flag is given - // create new block for writing + // create new block for writing let write = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); // create new block for return let ret = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - + // build if, true block is for setting write flag (write block), false block is return (ret block) LLVMBuildCondBr(llbuilder, write_flag_set, write, ret); @@ -106,19 +106,20 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMPositionBuilderAtEnd(llbuilder, ret); LLVMBuildRet(llbuilder, ptr); } - + // // start building model params access block LLVMPositionBuilderAtEnd(llbuilder, model_bb); - + // create switch statement, based on param_id, default block is opvar_bb - // number of cases: is the number of cases ok? + // number of cases: is the number of cases ok? // should it be inst_data.params.len()+model_data.params.len() - let switch_model = - LLVMBuildSwitch( - llbuilder, param_id, opvar_bb, - inst_data.params.len() as u32 + model_data.params.len() as u32 - ); + let switch_model = LLVMBuildSwitch( + llbuilder, + param_id, + opvar_bb, + inst_data.params.len() as u32 + model_data.params.len() as u32, + ); // build cases, one for each instance parameter // assumes osdi ids of instance parameters are 0..inst_data.params.len() @@ -129,8 +130,8 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); LLVMAddCase(switch_model, case, bb); - - // build code for getting the pointer to + + // build code for getting the pointer to // param_idx-th instance parameter in model structure let (ptr, _) = model_data.nth_inst_param_ptr(inst_data, param_idx as u32, model, llbuilder); @@ -159,7 +160,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let case = cx.const_unsigned_int((inst_data.params.len() + param_idx) as u32); LLVMAddCase(switch_model, case, bb); - // build code for getting the pointer to + // build code for getting the pointer to // param_idx-th model parameter in model structure let (ptr, _) = model_data.nth_param_ptr(param_idx as u32, model, llbuilder); @@ -176,11 +177,11 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMPositionBuilderAtEnd(llbuilder, ret); LLVMBuildRet(llbuilder, ptr); } - + // null pointer constant let null_ptr = cx.const_null_ptr(); - // + // // default case block if instance/model parameter with given osdi id not found LLVMPositionBuilderAtEnd(llbuilder, opvar_bb); // create switch based on param_id, default block is err_exit @@ -201,10 +202,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { ); LLVMAddCase(switch_opvar, case, bb); - // build code for getting the pointer to + // build code for getting the pointer to // param_idx-th opvar in instance structure let (ptr, _) = self.nth_opvar_ptr(opvar_idx as u32, inst, model, llbuilder); - + // return the pointer LLVMBuildRet(llbuilder, ptr); } @@ -226,9 +227,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let fun_ty = cx.ty_func(&[void_ptr, uint32_t], uint32_t); let name = &format!("given_flag_instance_{}", &self.module.sym); let llfunc = cx.declare_int_c_fn(name, fun_ty); - + let OsdiCompilationUnit { inst_data, cx, .. } = &self; - + unsafe { let zero = cx.const_int(0); let one = cx.const_int(1); @@ -238,14 +239,14 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llbuilder = LLVMCreateBuilderInContext(cx.llcx); LLVMPositionBuilderAtEnd(llbuilder, entry); - + // get params let ptr = LLVMGetParam(llfunc, 0); let param_id = LLVMGetParam(llfunc, 1); - + // // start building function body - + // create switch statement, based on param_id, default block is opvar_bb // number of cases obtained from inst_data let switch_inst = @@ -260,15 +261,15 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); LLVMAddCase(switch_inst, case, bb); - + // Build code for checking the parameter given flag let is_given = inst_data.is_nth_param_given(cx, param_idx as u32, ptr, llbuilder); let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); - + // Return value LLVMBuildRet(llbuilder, is_given); } - + // build not_found block LLVMPositionBuilderAtEnd(llbuilder, not_found); @@ -285,7 +286,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let fun_ty = cx.ty_func(&args_, cx.ty_int()); let name = &format!("given_flag_model_{}", self.module.sym); let llfunc = cx.declare_int_c_fn(name, fun_ty); - + unsafe { let zero = cx.const_int(0); let one = cx.const_int(1); @@ -295,19 +296,21 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llbuilder = LLVMCreateBuilderInContext(cx.llcx); LLVMPositionBuilderAtEnd(llbuilder, entry); - + // get params let ptr = LLVMGetParam(llfunc, 0); let param_id = LLVMGetParam(llfunc, 1); - + // // start building function body - + // create switch statement, based on param_id, default block is opvar_bb // number of cases obtained from inst_data let switch_inst = LLVMBuildSwitch( - llbuilder, param_id, not_found, - (model_data.params.len() + inst_data.params.len()) as u32 + llbuilder, + param_id, + not_found, + (model_data.params.len() + inst_data.params.len()) as u32, ); // build cases, one for each instance parameter @@ -319,11 +322,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); LLVMAddCase(switch_inst, case, bb); - + // Build code for checking the parameter given flag - let is_given = model_data.is_nth_inst_param_given(cx, param_idx as u32, ptr, llbuilder); + let is_given = + model_data.is_nth_inst_param_given(cx, param_idx as u32, ptr, llbuilder); let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); - + // Return value LLVMBuildRet(llbuilder, is_given); } @@ -337,15 +341,15 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // construct case constant, add case with building block bb let case = cx.const_unsigned_int((inst_data.params.len() + param_idx) as u32); LLVMAddCase(switch_inst, case, bb); - + // Build code for checking the parameter given flag let is_given = model_data.is_nth_param_given(cx, param_idx as u32, ptr, llbuilder); let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); - + // Return value LLVMBuildRet(llbuilder, is_given); } - + // build not_found block LLVMPositionBuilderAtEnd(llbuilder, not_found); @@ -355,5 +359,4 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { llfunc } - } diff --git a/openvaf/osdi/src/compilation_unit.rs b/openvaf/osdi/src/compilation_unit.rs index 204481c..e88fd98 100644 --- a/openvaf/osdi/src/compilation_unit.rs +++ b/openvaf/osdi/src/compilation_unit.rs @@ -2,13 +2,12 @@ use hir::CompilationDB; use hir_lower::fmt::{DisplayKind, FmtArg, FmtArgKind}; use hir_lower::{CallBackKind, HirInterner}; use lasso::Rodeo; -use llvm::Linkage; use llvm::{ IntPredicate, LLVMAddIncoming, LLVMAppendBasicBlockInContext, LLVMBuildAdd, LLVMBuildArrayMalloc, LLVMBuildBr, LLVMBuildCall2, LLVMBuildCondBr, LLVMBuildFMul, LLVMBuildFree, LLVMBuildICmp, LLVMBuildInBoundsGEP2, LLVMBuildLoad2, LLVMBuildPhi, LLVMGetParam, LLVMIsDeclaration, LLVMPositionBuilderAtEnd, LLVMSetLinkage, - LLVMSetUnnamedAddress, UnnamedAddr, UNNAMED, + LLVMSetUnnamedAddress, Linkage, UnnamedAddr, UNNAMED, }; use mir::{FuncRef, Function}; use mir_llvm::{CallbackFun, CodegenCx, LLVMBackend, ModuleLlvm}; diff --git a/openvaf/osdi/src/inst_data.rs b/openvaf/osdi/src/inst_data.rs index 76e02ac..5798d24 100644 --- a/openvaf/osdi/src/inst_data.rs +++ b/openvaf/osdi/src/inst_data.rs @@ -732,7 +732,7 @@ impl<'ll> OsdiInstanceData<'ll> { ptr: &'ll llvm::Value, llbuilder: &llvm::Builder<'ll>, reactive: bool, - has_offset: bool, + has_offset: bool, offset: &'ll llvm::Value, val: &'ll llvm::Value, ) { @@ -776,13 +776,13 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, entry: u32, - ty: &'ll llvm::Type, + ty: &'ll llvm::Type, ptr: &'ll llvm::Value, llbuilder: &llvm::Builder<'ll>, val: &'ll llvm::Value, ) { let zero = cx.const_int(0); - + // Convert to LLVM u32 let entry = cx.const_unsigned_int(entry); // Create pointer to array entry with index entry diff --git a/openvaf/osdi/src/lib.rs b/openvaf/osdi/src/lib.rs index f4b329f..3b18cce 100644 --- a/openvaf/osdi/src/lib.rs +++ b/openvaf/osdi/src/lib.rs @@ -1,9 +1,11 @@ +use std::ffi::CString; + use base_n::CASE_INSENSITIVE; use camino::{Utf8Path, Utf8PathBuf}; use hir::{CompilationDB, ParamSysFun, Type}; use hir_lower::{CallBackKind, HirInterner, ParamKind}; use lasso::Rodeo; -use llvm::{LLVMDisposeTargetData, OptLevel, LLVMABISizeOfType}; +use llvm::{LLVMABISizeOfType, LLVMDisposeTargetData, OptLevel}; use mir_llvm::{CodegenCx, LLVMBackend}; use salsa::ParallelDatabase; use sim_back::{CompiledModule, ModuleInfo}; @@ -11,8 +13,6 @@ use stdx::{impl_debug_display, impl_idx_from}; use target::spec::Target; use typed_indexmap::TiSet; -use std::ffi::CString; - use crate::compilation_unit::{new_codegen, OsdiCompilationUnit, OsdiModule}; use crate::metadata::osdi_0_4::OsdiTys; use crate::metadata::OsdiLimFunction; @@ -106,7 +106,7 @@ pub fn compile( assert_eq!(llmod.emit_object(path.as_ref()), Ok(())) } }); - + let _db = db.snapshot(); scope.spawn(move |_| { let name = format!("setup_model_{}", &module.sym); @@ -196,18 +196,13 @@ pub fn compile( cx.const_unsigned_int(OSDI_VERSION.1), true, ); - + let descr_size: u32; unsafe { descr_size = LLVMABISizeOfType(target_data, tys.osdi_descriptor) as u32; } - cx.export_val( - "OSDI_DESCRIPTOR_SIZE", - cx.ty_int(), - cx.const_unsigned_int(descr_size), - true, - ); + cx.export_val("OSDI_DESCRIPTOR_SIZE", cx.ty_int(), cx.const_unsigned_int(descr_size), true); if !lim_table.is_empty() { let lim: Vec<_> = lim_table.iter().map(|entry| entry.to_ll_val(&cx, &tys)).collect(); diff --git a/openvaf/osdi/src/load.rs b/openvaf/osdi/src/load.rs index 6499a12..cabc333 100644 --- a/openvaf/osdi/src/load.rs +++ b/openvaf/osdi/src/load.rs @@ -84,7 +84,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { NoiseSourceKind::NoiseTable { .. } => unimplemented!("noise tables"), }; // Multiply with squared factor because factor is in terms of signal, but - // we are computing the power, which is scaled by factor**2. + // we are computing the power, which is scaled by factor**2. pwr = LLVMBuildFMul(llbuilder, pwr, fac, UNNAMED); LLVMSetFastMath(pwr); pwr = LLVMBuildFMul(llbuilder, pwr, fac, UNNAMED); @@ -282,9 +282,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { pub fn load_jacobian(&self, kind: JacobianLoadType, with_offset: bool) -> &'ll llvm::Value { let OsdiCompilationUnit { cx, module, .. } = *self; let fun_ty = if !with_offset { - if kind.read_reactive() { + if kind.read_reactive() { cx.ty_func(&[cx.ty_ptr(), cx.ty_ptr(), cx.ty_double()], cx.ty_void()) - } else { + } else { cx.ty_func(&[cx.ty_ptr(), cx.ty_ptr()], cx.ty_void()) } } else { @@ -307,16 +307,16 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let inst = LLVMGetParam(llfunc, 0); let model = LLVMGetParam(llfunc, 1); let alpha = if !with_offset && kind.read_reactive() { - // Reactive part - LLVMGetParam(llfunc, 2) - } else { + // Reactive part + LLVMGetParam(llfunc, 2) + } else { // Some dummy - inst + inst }; let offset = if with_offset { LLVMGetParam(llfunc, 2) } else { - // Some dummy + // Some dummy inst }; @@ -354,8 +354,8 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { inst, llbuilder, kind.dst_reactive(), - with_offset, - offset, + with_offset, + offset, res, ); } @@ -364,14 +364,14 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMBuildRetVoid(llbuilder); LLVMDisposeBuilder(llbuilder); } - + llfunc } - + // write_jacobian_array_{resist|react|tran}(void* instance, void* model, double* destination [, alpha]) // Writes Jacobian entries into a double array of size num_jacobian_entries - // If a particular entry is not present, nothing is loaded. - // Array of doubles need not be zeroed before calling this function. + // If a particular entry is not present, nothing is loaded. + // Array of doubles need not be zeroed before calling this function. pub fn write_jacobian_array(&self, kind: JacobianLoadType) -> &'ll llvm::Value { let OsdiCompilationUnit { cx, module, .. } = *self; let args = [cx.ty_ptr(), cx.ty_ptr(), cx.ty_ptr()]; @@ -398,8 +398,8 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } }; let dest_ty = cx.ty_array(cx.ty_double(), len as u32); - - let mut pos : u32 = 0; + + let mut pos: u32 = 0; for entry in module.dae_system.jacobian.keys() { let res = { if kind.read_resistive() { @@ -410,27 +410,20 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { self.load_jacobian_entry(entry, inst, model, llbuilder, true) } }; - + // Do we have any result in res if let Some(res) = res { // Store it in array pointed to by ptr - self.inst_data.write_jacobian_contrib( - self.cx, - pos, - dest_ty, - dest_array, - llbuilder, - res, - ); + self.inst_data + .write_jacobian_contrib(self.cx, pos, dest_ty, dest_array, llbuilder, res); pos = pos + 1; } } - + LLVMBuildRetVoid(llbuilder); LLVMDisposeBuilder(llbuilder); } - + llfunc } - } diff --git a/openvaf/osdi/src/metadata.rs b/openvaf/osdi/src/metadata.rs index fd360c2..ab9a07c 100644 --- a/openvaf/osdi/src/metadata.rs +++ b/openvaf/osdi/src/metadata.rs @@ -12,7 +12,7 @@ use smol_str::SmolStr; use crate::compilation_unit::{OsdiCompilationUnit, OsdiModule}; use crate::inst_data::{ - OsdiInstanceParam, COLLAPSED, JACOBIAN_PTR_REACT, JACOBIAN_PTR_RESIST, NODE_MAPPING, STATE_IDX + OsdiInstanceParam, COLLAPSED, JACOBIAN_PTR_REACT, JACOBIAN_PTR_RESIST, NODE_MAPPING, STATE_IDX, }; use crate::load::JacobianLoadType; use crate::metadata::osdi_0_4::{ @@ -232,13 +232,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } pub fn inputs(&self) -> Vec { - self.module.dae_system.model_inputs.iter().map(|(node1, node2)| { - OsdiNodePair { - node_1: (*node1).into(), - node_2: (*node2).into(), - } - }) - .collect() + self.module + .dae_system + .model_inputs + .iter() + .map(|(node1, node2)| OsdiNodePair { node_1: (*node1).into(), node_2: (*node2).into() }) + .collect() } pub fn descriptor( @@ -249,7 +248,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let collapsible = self.collapsible(); let inputs = self.inputs(); let OsdiCompilationUnit { ref inst_data, ref model_data, module, cx, .. } = *self; - + unsafe { let node_mapping_offset = LLVMOffsetOfElement(target_data, inst_data.ty, NODE_MAPPING) as u32; @@ -260,7 +259,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let bound_step_offset = inst_data.bound_step_elem().map_or(u32::MAX, |elem| { LLVMOffsetOfElement(target_data, inst_data.ty, elem) as u32 }); - + let state_idx_off = LLVMOffsetOfElement(target_data, inst_data.ty, STATE_IDX) as u32; let instance_size = LLVMABISizeOfType(target_data, inst_data.ty) as u32; @@ -319,15 +318,16 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { num_states: self.module.intern.lim_state.len() as u32, load_limit_rhs_resist: self.load_lim_rhs(false), load_limit_rhs_react: self.load_lim_rhs(true), - given_flag_model: self.given_flag_model(), - given_flag_instance: self.given_flag_instance(), - num_resistive_jacobian_entries: module.dae_system.num_resistive, - num_reactive_jacobian_entries: module.dae_system.num_reactive, + given_flag_model: self.given_flag_model(), + given_flag_instance: self.given_flag_instance(), + num_resistive_jacobian_entries: module.dae_system.num_resistive, + num_reactive_jacobian_entries: module.dae_system.num_reactive, write_jacobian_array_resist: self.write_jacobian_array(JacobianLoadType::Resist), write_jacobian_array_react: self.write_jacobian_array(JacobianLoadType::React), - num_inputs: inputs.len() as u32, - inputs: inputs, - load_jacobian_with_offset_resist: self.load_jacobian(JacobianLoadType::Resist, true), + num_inputs: inputs.len() as u32, + inputs, + load_jacobian_with_offset_resist: self + .load_jacobian(JacobianLoadType::Resist, true), load_jacobian_with_offset_react: self.load_jacobian(JacobianLoadType::React, true), } } diff --git a/openvaf/osdi/src/setup.rs b/openvaf/osdi/src/setup.rs index ec3908d..2491803 100644 --- a/openvaf/osdi/src/setup.rs +++ b/openvaf/osdi/src/setup.rs @@ -1,5 +1,4 @@ use hir_lower::{CallBackKind, ParamInfoKind, ParamKind, PlaceKind}; - use llvm::IntPredicate::IntSLT; use llvm::{ LLVMAppendBasicBlockInContext, LLVMBuildBr, LLVMBuildCondBr, LLVMBuildRetVoid, diff --git a/openvaf/preprocessor/src/processor.rs b/openvaf/preprocessor/src/processor.rs index e87b8f5..a9cb641 100755 --- a/openvaf/preprocessor/src/processor.rs +++ b/openvaf/preprocessor/src/processor.rs @@ -176,13 +176,13 @@ impl<'a> Processor<'a> { if new_args.len() > def.arg_cnt { // macro definition has no arguments, but some were parsed as part of the call // so put the arguments back - dst.push( Token { kind:L_PAREN, span } ); + dst.push(Token { kind: L_PAREN, span }); for arg in new_args { for tok in arg { dst.push(tok) } } - dst.push( Token { kind:R_PAREN, span } ); + dst.push(Token { kind: R_PAREN, span }); } } else { errors.push(MacroArgumentCountMismatch { @@ -255,7 +255,7 @@ impl<'a> Processor<'a> { } else { err.push(PreprocessorDiagnostic::MacroNotDefined { name: name.to_owned(), - span: p.current_span() + span: p.current_span(), }) } p.bump(); @@ -264,7 +264,7 @@ impl<'a> Processor<'a> { let name = p.current_text(); err.push(PreprocessorDiagnostic::UnsupportedCompDir { name: name.to_owned(), - span: p.current_span() + span: p.current_span(), }); p.bump(); } diff --git a/openvaf/sim_back/src/dae.rs b/openvaf/sim_back/src/dae.rs index cd222f1..395f00e 100644 --- a/openvaf/sim_back/src/dae.rs +++ b/openvaf/sim_back/src/dae.rs @@ -44,10 +44,10 @@ pub struct DaeSystem { /// noise pub noise_sources: Vec, /// model inputs (node pairs) - pub model_inputs: Vec<(u32, u32)>, + pub model_inputs: Vec<(u32, u32)>, /// Jacobian entry counts - pub num_resistive : u32, - pub num_reactive : u32, + pub num_resistive: u32, + pub num_reactive: u32, } impl DaeSystem { diff --git a/openvaf/sim_back/src/dae/builder.rs b/openvaf/sim_back/src/dae/builder.rs index 4ae4605..a8ee700 100644 --- a/openvaf/sim_back/src/dae/builder.rs +++ b/openvaf/sim_back/src/dae/builder.rs @@ -4,13 +4,13 @@ use std::vec; use ahash::AHashMap; use bitset::BitSet; use hir::{BranchWrite, CompilationDB, Node, ParamSysFun}; -use hir_lower::{HirInterner, ImplicitEquation, ParamKind, CurrentKind}; +use hir_lower::{CurrentKind, HirInterner, ImplicitEquation, ParamKind}; use indexmap::IndexSet; use mir::builder::InstBuilder; use mir::cursor::{Cursor, FuncCursor}; use mir::{ strip_optbarrier, Block, ControlFlowGraph, DominatorTree, Inst, KnownDerivatives, Unknown, - Value, FALSE, F_ZERO, TRUE, F_ONE + Value, FALSE, F_ONE, F_ZERO, TRUE, }; use mir_autodiff::auto_diff; use typed_index_collections::TiVec; @@ -112,7 +112,7 @@ impl<'a> Builder<'a> { let (nres, nreact) = self.count_jacobian_entries(); self.system.num_resistive = nres; self.system.num_reactive = nreact; - + self.system } @@ -157,8 +157,7 @@ impl<'a> Builder<'a> { // Create a list of input node pairs corresponding to all model inputs fn build_input_unknown_pairs(&mut self) { self.system.model_inputs.clear(); - for (_, &kind, _) in self.intern - .live_params(&self.cursor.func.dfg) { + for (_, &kind, _) in self.intern.live_params(&self.cursor.func.dfg) { match kind { ParamKind::Voltage { hi, lo } => { let mut ih = std::u32::MAX; @@ -166,22 +165,22 @@ impl<'a> Builder<'a> { let uh = SimUnknownKind::KirchoffLaw(hi); if let Some(uh) = self.system.unknowns.index(&uh) { ih = u32::from(uh); - } + } if let Some(lo) = lo { let ul = SimUnknownKind::KirchoffLaw(lo); if let Some(ul) = self.system.unknowns.index(&ul) { il = u32::from(ul); } } - if ih!=std::u32::MAX && il!=std::u32::MAX { + if ih != std::u32::MAX && il != std::u32::MAX { self.system.model_inputs.push((ih, il)); } - }, - ParamKind::Current ( cur_kind ) => { + } + ParamKind::Current(cur_kind) => { match cur_kind { - CurrentKind::Port (_) => { + CurrentKind::Port(_) => { // TODO? - }, + } _ => { let u = SimUnknownKind::Current(cur_kind); if let Some(u) = self.system.unknowns.index(&u) { @@ -189,18 +188,18 @@ impl<'a> Builder<'a> { } } } - }, + } ParamKind::ImplicitUnknown(ieq_kind) => { let u = SimUnknownKind::Implicit(ieq_kind); if let Some(u) = self.system.unknowns.index(&u) { self.system.model_inputs.push((u32::from(u), std::u32::MAX)); } - }, + } _ => {} } } } - + fn count_jacobian_entries(&mut self) -> (u32, u32) { // Count resistive and reactive Jacobian entries let mut nres: u32 = 0; @@ -467,13 +466,13 @@ impl<'a> Builder<'a> { self.cfg.add_edge(start_bb, voltage_src_bb); self.cfg.add_edge(start_bb, next_block); self.cfg.add_edge(voltage_src_bb, next_block); - + // Debugging // println!("start bb {:?}", start_bb); // println!("voltage src bb {:?}", voltage_src_bb); // println!("next block {:?}", next_block); // println!("cursor at {:?}", self.cursor.position()); - + // Get expression (condition) that determines if branch acts as a voltage source // Skip trailing optbarriers let is_voltage_src = @@ -511,54 +510,43 @@ impl<'a> Builder<'a> { ); } - fn mfactor_multiply(&mut self, mfactor: Value, srcfactor : Value) -> Value { + fn mfactor_multiply(&mut self, mfactor: Value, srcfactor: Value) -> Value { match (mfactor, srcfactor) { // Leave srcfactor unchanged if mfactor is 1 (F_ONE, fac) => fac, // mfactor is not 1 - // Note that srcfactor is the signal scaling factor. - // Because power scales with mfactor the signal scales with - // sqrt(mfactor). + // Note that srcfactor is the signal scaling factor. + // Because power scales with mfactor the signal scales with + // sqrt(mfactor). (mfactor, srcfactor) => { - let sqrt_mfactor = self.cursor - .ins() - .sqrt(mfactor); + let sqrt_mfactor = self.cursor.ins().sqrt(mfactor); if srcfactor == F_ONE { // Old factor is 1, replace it with sqrt(mfactor) sqrt_mfactor } else { // Multiply old factor with sqrt(mfactor) - self.cursor - .ins() - .fmul(srcfactor, sqrt_mfactor) + self.cursor.ins().fmul(srcfactor, sqrt_mfactor) } } } } - fn mfactor_divide(&mut self, mfactor: Value, srcfactor : Value) -> Value { + fn mfactor_divide(&mut self, mfactor: Value, srcfactor: Value) -> Value { match (mfactor, srcfactor) { // Leave srcfactor unchanged if mfactor is 1 (F_ONE, fac) => fac, // mfactor is not 1 - // Note that srcfactor is the signal scaling factor. - // Because power scales with mfactor the signal scales with - // sqrt(mfactor). + // Note that srcfactor is the signal scaling factor. + // Because power scales with mfactor the signal scales with + // sqrt(mfactor). (mfactor, srcfactor) => { - let sqrt_mfactor = self.cursor - .ins() - .sqrt(mfactor); - self.cursor - .ins() - .fdiv(srcfactor, sqrt_mfactor) + let sqrt_mfactor = self.cursor.ins().sqrt(mfactor); + self.cursor.ins().fdiv(srcfactor, sqrt_mfactor) } } } - fn current_branch( - &mut self, - BranchInfo { current_src, .. }: &BranchInfo, - ) -> Contribution { + fn current_branch(&mut self, BranchInfo { current_src, .. }: &BranchInfo) -> Contribution { let mfactor = self .intern .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); @@ -580,10 +568,7 @@ impl<'a> Builder<'a> { } } - fn voltage_branch( - &mut self, - BranchInfo { voltage_src, .. }: &BranchInfo, - ) -> Contribution { + fn voltage_branch(&mut self, BranchInfo { voltage_src, .. }: &BranchInfo) -> Contribution { let mfactor = self .intern .ensure_param(&mut self.cursor, ParamKind::ParamSysFun(ParamSysFun::mfactor)); @@ -627,7 +612,7 @@ impl<'a> Builder<'a> { let current = current_src.unknown.unwrap(); let unknown = select(voltage, current); // Build noise phi commands - // Voltage noise, for each noise add a phi instruction that joins the values for + // Voltage noise, for each noise add a phi instruction that joins the values for // the case the switch branch behaves as a voltage source (source value) and as a current source (0) let mut noise = Vec::with_capacity(voltage_src.noise.len() + current_src.noise.len()); let voltage_noise = voltage_src.noise.iter().map(|src| { @@ -636,7 +621,7 @@ impl<'a> Builder<'a> { src }); noise.extend(voltage_noise); - // Current noise, for each noise add a phi instruction that joins the values for + // Current noise, for each noise add a phi instruction that joins the values for // the case the switch branch behaves as a voltage source (0) and as a current source (source value) let current_noise = current_src.noise.iter().map(|src| { let mut src = src.clone(); @@ -647,15 +632,10 @@ impl<'a> Builder<'a> { // Build remaining phi commands let phi_resist = select(voltage_src.resist, current_src.resist); let phi_react = select(voltage_src.react, current_src.react); - let phi_resist_ss = select( - voltage_src.resist_small_signal, - current_src.resist_small_signal - ); - let phi_react_ss = select( - voltage_src.react_small_signal, - current_src.react_small_signal - ); - // Scale noise + let phi_resist_ss = + select(voltage_src.resist_small_signal, current_src.resist_small_signal); + let phi_react_ss = select(voltage_src.react_small_signal, current_src.react_small_signal); + // Scale noise // Must do this after all phi commands // because all phi commands must be listed at block beginning let mfactor = self @@ -670,7 +650,7 @@ impl<'a> Builder<'a> { noise[ii].factor = self.mfactor_multiply(mfactor, noise[ii].factor); } } - + Contribution { unknown: Some(unknown), resist: phi_resist, @@ -698,7 +678,7 @@ impl<'a> Builder<'a> { let hi = self.ensure_unknown(hi); let lo = lo.map(|lo| self.ensure_unknown(lo)); self.system.noise_sources.extend(contrib.noise.iter().map(|src| { - let factor = src.factor; + let factor = src.factor; NoiseSource { name: src.name, kind: src.kind.clone(), hi, lo, factor } })) } diff --git a/openvaf/sim_back/src/lib.rs b/openvaf/sim_back/src/lib.rs index 7d5f4e0..65d8593 100644 --- a/openvaf/sim_back/src/lib.rs +++ b/openvaf/sim_back/src/lib.rs @@ -3,9 +3,8 @@ use hir_lower::{CurrentKind, HirInterner, ImplicitEquation, ParamKind}; use lasso::Rodeo; use mir::Function; use mir_opt::{simplify_cfg, sparse_conditional_constant_propagation}; -use stdx::impl_debug_display; - pub use module_info::{collect_modules, ModuleInfo}; +use stdx::impl_debug_display; use crate::context::{Context, OptimiziationStage}; use crate::dae::DaeSystem; @@ -149,22 +148,22 @@ impl<'a> CompiledModule<'a> { let cu = db.compilation_unit(); println!("Compilation unit: {}", cu.name(db)); - + let m = module.module; println!("Module: {:?}", m.name(db)); println!("Ports: {:?}", m.ports(db)); println!("Internal nodes: {:?}", m.internal_nodes(db)); - + println!("DAE system"); let str = format!("{dae_system:#?}"); println!("{}", str); println!(""); - + println!("CX function"); println!("{:?}", cx.func); println!(""); } - + debug_assert!(cx.func.validate()); cx.refresh_op_dependent_insts(); @@ -178,9 +177,9 @@ impl<'a> CompiledModule<'a> { println!("{:?}", init.func); println!(""); } - + debug_assert!(init.func.validate()); - + // TODO: refactor param intilization to use tables let inst_params: Vec<_> = module .params diff --git a/openvaf/sim_back/src/node_collapse.rs b/openvaf/sim_back/src/node_collapse.rs index 737db91..ef88c2e 100644 --- a/openvaf/sim_back/src/node_collapse.rs +++ b/openvaf/sim_back/src/node_collapse.rs @@ -22,7 +22,11 @@ pub struct NodeCollapse { } impl NodeCollapse { - pub(super) fn new(init: &Initialization, dae_system: &DaeSystem, ctx: &Context) -> NodeCollapse { + pub(super) fn new( + init: &Initialization, + dae_system: &DaeSystem, + ctx: &Context, + ) -> NodeCollapse { let mut pairs = TiSet::with_capacity(32); for (&kind, _) in &init.intern.outputs { if let PlaceKind::CollapseImplicitEquation(eq) = kind { diff --git a/openvaf/sim_back/src/util.rs b/openvaf/sim_back/src/util.rs index ff973a3..c5ab78f 100644 --- a/openvaf/sim_back/src/util.rs +++ b/openvaf/sim_back/src/util.rs @@ -46,9 +46,9 @@ pub fn update_optbarrier( } pub fn add(cursor: &mut FuncCursor, dst: &mut Value, val: Value, negate: bool) { - // Create MIR instruction that takes the destination value and adds or subtracts val. - // Returns the resulting value produced by fadd/fsub. - // Sets dst to this new value. + // Create MIR instruction that takes the destination value and adds or subtracts val. + // Returns the resulting value produced by fadd/fsub. + // Sets dst to this new value. match (*dst, val) { // val is zero, nothing to do (_, F_ZERO) => (), @@ -57,8 +57,8 @@ pub fn add(cursor: &mut FuncCursor, dst: &mut Value, val: Value, negate: bool) { // dst is zero, no negate, create optbarrier // If not a node with only a voltage noise contribution will produce a singular Jacobian // The KCL entry of the node in the Jacobian will be missing the branch current contribution - // (F_ZERO, _) => *dst = val, - (F_ZERO, _) => *dst = cursor.ins().optbarrier(val), + // (F_ZERO, _) => *dst = val, + (F_ZERO, _) => *dst = cursor.ins().optbarrier(val), // negate, create "fsub dst, val" (old, _) if negate => *dst = cursor.ins().fsub(old, val), // do not negate, create "fadd dst, val" diff --git a/openvaf/syntax/src/ast.rs b/openvaf/syntax/src/ast.rs index ce8a760..faf31ae 100644 --- a/openvaf/syntax/src/ast.rs +++ b/openvaf/syntax/src/ast.rs @@ -126,11 +126,10 @@ impl Iterator for AstChildTokens { } pub(crate) mod support { - use crate::ast::RevAstChildren; - use super::{ AstChildTokens, AstChildren, AstNode, AstToken, SyntaxKind, SyntaxNode, SyntaxToken, }; + use crate::ast::RevAstChildren; pub(crate) fn child(parent: &SyntaxNode) -> Option { parent.children().find_map(N::cast) diff --git a/openvaf/target/src/spec/apple_base.rs b/openvaf/target/src/spec/apple_base.rs index c8a9368..34961d5 100644 --- a/openvaf/target/src/spec/apple_base.rs +++ b/openvaf/target/src/spec/apple_base.rs @@ -1,6 +1,5 @@ -use crate::spec::TargetOptions; - use super::LinkerFlavor; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { TargetOptions { diff --git a/sourcegen/src/hir_builtins.rs b/sourcegen/src/hir_builtins.rs index 75bf668..686f228 100644 --- a/sourcegen/src/hir_builtins.rs +++ b/sourcegen/src/hir_builtins.rs @@ -1,9 +1,10 @@ -use crate::{add_preamble, ensure_file_contents, project_root, reformat, to_upper_snake_case}; use indexmap::IndexSet; use quote::{format_ident, quote}; use stdx::iter::multiunzip; use stdx::SKIP_HOST_TESTS; +use crate::{add_preamble, ensure_file_contents, project_root, reformat, to_upper_snake_case}; + const ANALOG_OPERATORS: [&str; 17] = [ "absdelay", "ddt", diff --git a/verilogae/verilogae/src/compiler_db.rs b/verilogae/verilogae/src/compiler_db.rs index 1d065d1..543768c 100644 --- a/verilogae/verilogae/src/compiler_db.rs +++ b/verilogae/verilogae/src/compiler_db.rs @@ -7,6 +7,7 @@ use basedb::diagnostics::{ConsoleSink, Diagnostic, DiagnosticSink, Label, LabelS use basedb::lints::LintLevel; use basedb::{BaseDB, FileId, VfsPath}; use camino::Utf8Path; +pub use hir::CompilationDB; use hir::{ Branch, BranchKind, Module, Node, Parameter, PathResolveError, ScopeDef, Type, Variable, }; @@ -22,8 +23,6 @@ use syntax::{AstNode, TextRange}; use crate::opts::abs_path; use crate::Opts; -pub use hir::CompilationDB; - pub(crate) fn new(root_file: &Utf8Path, opts: &Opts) -> Result { let vfs = opts.vfs()?; let (root_file, root_file_contents) = if vfs.is_some() { diff --git a/verilogae/verilogae/src/lib.rs b/verilogae/verilogae/src/lib.rs index c0e091f..a124fa1 100644 --- a/verilogae/verilogae/src/lib.rs +++ b/verilogae/verilogae/src/lib.rs @@ -6,7 +6,12 @@ use anyhow::{bail, Context, Result}; use basedb::VfsStorage; use camino::{Utf8Path, Utf8PathBuf}; use lasso::Rodeo; +#[cfg(unix)] +use libloading::os::unix::Library; +#[cfg(windows)] +use libloading::os::windows::Library; use linker::link; +pub use llvm::OptLevel; use mir_llvm::LLVMBackend; use salsa::ParallelDatabase; use stdx::iter::zip; @@ -18,13 +23,6 @@ use crate::api::{Opts, VfsEntry}; use crate::compiler_db::{CompilationDB, ModelInfo}; use crate::middle::{build_module_mir, build_param_init_mir}; use crate::opts::abs_path; -pub use llvm::OptLevel; - -#[cfg(windows)] -use libloading::os::windows::Library; - -#[cfg(unix)] -use libloading::os::unix::Library; pub mod api; mod back; diff --git a/verilogae/verilogae_ffi/src/lib.rs b/verilogae/verilogae_ffi/src/lib.rs index 19f42f0..18256a2 100644 --- a/verilogae/verilogae_ffi/src/lib.rs +++ b/verilogae/verilogae_ffi/src/lib.rs @@ -1,10 +1,9 @@ #[cfg(not(feature = "static"))] mod ffi; +pub use ffi::*; #[cfg(feature = "static")] use verilogae::api as ffi; -pub use ffi::*; - #[cfg(feature = "static")] pub const PARAM_FLAGS_MIN_INCLUSIVE: ParamFlags = 1; #[cfg(feature = "static")] diff --git a/verilogae/verilogae_py/src/lib.rs b/verilogae/verilogae_py/src/lib.rs index 599ef3c..fe150a6 100644 --- a/verilogae/verilogae_py/src/lib.rs +++ b/verilogae/verilogae_py/src/lib.rs @@ -12,10 +12,11 @@ mod util; use std::os::raw::{c_char, c_int}; use std::ptr; +use pyo3_ffi::*; + use crate::load::{load_info_py, load_py, load_vfs}; use crate::model::{VAE_FUNCTION_TY, VAE_MODEL_TY, VAE_PARAM_TY}; use crate::typeref::init_typerefs; -use pyo3_ffi::*; #[cfg(Py_3_8)] const FUN_FLAG: c_int = METH_FASTCALL; diff --git a/verilogae/verilogae_py/src/load.rs b/verilogae/verilogae_py/src/load.rs index 0e160bb..51129dc 100644 --- a/verilogae/verilogae_py/src/load.rs +++ b/verilogae/verilogae_py/src/load.rs @@ -1,3 +1,5 @@ +use std::ptr; + use libc::c_char; use pyo3_ffi::*; use verilogae_ffi::{verilogae_load, Opts, Slice, Vfs, VfsEntry, VfsExport}; @@ -8,8 +10,6 @@ use crate::typeref; use crate::unicode::OsStr; use crate::util::unlikely; -use std::ptr; - macro_rules! handle_opt { ($fun: literal, $dst: expr, $arg: expr, $val: expr) => { if $arg == typeref::MODULE_STR { diff --git a/verilogae/verilogae_py/src/model.rs b/verilogae/verilogae_py/src/model.rs index 121e7c9..982b007 100644 --- a/verilogae/verilogae_py/src/model.rs +++ b/verilogae/verilogae_py/src/model.rs @@ -1,8 +1,7 @@ use std::ffi::CStr; use std::mem::take; use std::os::raw::c_long; -use std::ptr; -use std::slice; +use std::{ptr, slice}; use libc::{c_char, c_void}; use pyo3_ffi::structmember::{PyMemberDef, READONLY, T_OBJECT, T_OBJECT_EX}; @@ -27,13 +26,10 @@ use verilogae_ffi::{ use crate::ffi::new_type; use crate::numpy::{ItemType, NumpyArray, PyArrayError}; -use crate::typeref::NUMPY_API; -use crate::typeref::NUMPY_ARR_TYPE; -use crate::typeref::TEMPERATURE_STR; -use crate::typeref::VOLTAGES_STR; -use crate::typeref::{CURRENTS_STR, NUMPY_CDOUBLE_DESCR}; -use crate::util::likely; -use crate::util::unlikely; +use crate::typeref::{ + CURRENTS_STR, NUMPY_API, NUMPY_ARR_TYPE, NUMPY_CDOUBLE_DESCR, TEMPERATURE_STR, VOLTAGES_STR, +}; +use crate::util::{likely, unlikely}; pub static mut VAE_MODEL_TY: PyTypeObject = { let mut res = new_type::(); diff --git a/xtask/src/msvcrt.rs b/xtask/src/msvcrt.rs index 6ad3f6e..0629b86 100644 --- a/xtask/src/msvcrt.rs +++ b/xtask/src/msvcrt.rs @@ -1,9 +1,9 @@ use std::path::Path; -use crate::flags::GenMsvcrt; - use anyhow::Result; use xshell::{cmd, Shell}; + +use crate::flags::GenMsvcrt; const MINGW_URL: &str = "https://github.com/mirror/mingw-w64.git"; const UCRT_FILES: &[&str] = &[ From e45a31f0da98aae645f30e0a7dfd84df6ec07421 Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Wed, 30 Oct 2024 16:26:20 +0100 Subject: [PATCH 2/9] Deleting llvm --- include/verilogae.hpp | 4 +- melange/core/src/veriloga.rs | 7 +- openvaf/llvm/Cargo.toml | 23 -- openvaf/llvm/build.rs | 397 ---------------------- openvaf/llvm/src/attributes.rs | 34 -- openvaf/llvm/src/basic_block.rs | 37 -- openvaf/llvm/src/bitcode.rs | 19 -- openvaf/llvm/src/builder.rs | 419 ----------------------- openvaf/llvm/src/context.rs | 22 -- openvaf/llvm/src/initialization.rs | 263 -------------- openvaf/llvm/src/lib.rs | 366 -------------------- openvaf/llvm/src/module.rs | 136 -------- openvaf/llvm/src/object.rs | 162 --------- openvaf/llvm/src/pass_manager.rs | 82 ----- openvaf/llvm/src/support.rs | 88 ----- openvaf/llvm/src/targets.rs | 113 ------ openvaf/llvm/src/types.rs | 127 ------- openvaf/llvm/src/util.rs | 9 - openvaf/llvm/src/values.rs | 434 ------------------------ openvaf/llvm/wrapper/OpenVafWrapper.cpp | 47 --- openvaf/mir_llvm/Cargo.toml | 6 +- 21 files changed, 11 insertions(+), 2784 deletions(-) delete mode 100644 openvaf/llvm/Cargo.toml delete mode 100644 openvaf/llvm/build.rs delete mode 100644 openvaf/llvm/src/attributes.rs delete mode 100644 openvaf/llvm/src/basic_block.rs delete mode 100644 openvaf/llvm/src/bitcode.rs delete mode 100644 openvaf/llvm/src/builder.rs delete mode 100644 openvaf/llvm/src/context.rs delete mode 100644 openvaf/llvm/src/initialization.rs delete mode 100644 openvaf/llvm/src/lib.rs delete mode 100644 openvaf/llvm/src/module.rs delete mode 100644 openvaf/llvm/src/object.rs delete mode 100644 openvaf/llvm/src/pass_manager.rs delete mode 100644 openvaf/llvm/src/support.rs delete mode 100644 openvaf/llvm/src/targets.rs delete mode 100644 openvaf/llvm/src/types.rs delete mode 100644 openvaf/llvm/src/util.rs delete mode 100644 openvaf/llvm/src/values.rs delete mode 100644 openvaf/llvm/wrapper/OpenVafWrapper.cpp diff --git a/include/verilogae.hpp b/include/verilogae.hpp index 9e7a2ad..07189e9 100644 --- a/include/verilogae.hpp +++ b/include/verilogae.hpp @@ -20,7 +20,7 @@ namespace vae { namespace vae { -enum class OptLevel { +enum class LLVMCodeGenOptLevel { None = 0, Less = 1, Default = 2, @@ -66,7 +66,7 @@ struct Opts { Slice> allow_lints; Slice> warn_lints; Slice> deny_lints; - OptLevel opt_lvl; + LLVMCodeGenOptLevel opt_lvl; Slice target_cpu; Slice target; Slice> cg_flags; diff --git a/melange/core/src/veriloga.rs b/melange/core/src/veriloga.rs index e514df6..f381728 100644 --- a/melange/core/src/veriloga.rs +++ b/melange/core/src/veriloga.rs @@ -9,7 +9,8 @@ use libc::c_void; use libloading::Library; use log::{debug, error, info, warn}; use openvaf::{ - AbsPathBuf, CompilationDestination, CompilationTermination, LintLevel, OptLevel, Target, + AbsPathBuf, CompilationDestination, CompilationTermination, LLVMCodeGenOptLevel, LintLevel, + Target, }; pub(crate) use osdi_0_4::{ ANALYSIS_AC, ANALYSIS_DC, ANALYSIS_IC, ANALYSIS_NOISE, ANALYSIS_STATIC, ANALYSIS_TRAN, @@ -36,7 +37,7 @@ pub struct Opts { pub cache_dir: Option, pub lints: Vec<(String, LintLevel)>, include: Vec, - pub opt_lvl: Option, + pub opt_lvl: Option, } impl Opts { @@ -68,7 +69,7 @@ pub fn compile_va(path: &Utf8Path, opts: &Opts) -> Result ! { - println!("\n\n{}\n\n", s); - std::process::exit(1); -} - -#[track_caller] -pub fn output(cmd: &mut Command) -> String { - let output = match cmd.stderr(Stdio::inherit()).output() { - Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), - }; - if !output.status.success() { - panic!( - "command did not execute successfully: {:?}\n\ - expected success, got: {}", - cmd, output.status - ); - } - String::from_utf8(output.stdout).unwrap() -} - -pub fn rerun_if_changed_anything_in_dir(dir: &Path) { - let mut stack = dir - .read_dir() - .unwrap() - .map(|e| e.unwrap()) - .filter(|e| &*e.file_name() != ".git") - .collect::>(); - while let Some(entry) = stack.pop() { - let path = entry.path(); - if entry.file_type().unwrap().is_dir() { - stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); - } else { - println!("cargo:rerun-if-changed={}", path.display()); - } - } -} - -/// Reads an environment variable and adds it to dependencies. -/// Supposed to be used for all variables except those set for build scripts by cargo -/// -fn tracked_env_var_os + Display>(key: K) -> Option { - println!("cargo:rerun-if-env-changed={}", key); - env::var_os(key) -} - -fn detect_llvm_link() -> (&'static str, &'static str) { - // Force the link mode we want, preferring static by default, but - // possibly overridden by `configure --enable-llvm-link-shared`. - if tracked_env_var_os("LLVM_LINK_SHARED").is_some() { - ("dylib", "--link-shared") - } else { - ("static", "--link-static") - } -} - -fn winepath(path: &str) -> PathBuf { - let mut cmd = Command::new("winepath"); - cmd.arg(path); - let path = output(&mut cmd); - Path::new(path.trim()).to_owned() -} - -fn main() { - if std::env::var("COMPILER_NAME").is_err() { - println!("cargo:rustc-env=COMPILER_NAME=openvaf"); - } - - if tracked_env_var_os("RUST_CHECK").is_some() { - // If we're just running `check`, there's no need for LLVM to be built. - return; - } - - // build_helper::restore_library_path(); - - // let target = env::var("TARGET").expect("TARGET was not set"); - let llvm_config = tracked_env_var_os("LLVM_CONFIG").map(PathBuf::from); - // TODO provide mechanism to build llvm yourself - // .unwrap_or_else(|| { - // if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) { - // let to_test = dir - // .parent() - // .unwrap() - // .parent() - // .unwrap() - // .join(&target) - // .join("llvm/bin/llvm-config"); - // if Command::new(&to_test).output().is_ok() { - // return Some(to_test); - // } - // } - // None - // }); - - if let Some(llvm_config) = &llvm_config { - println!("cargo:rerun-if-changed={}", llvm_config.display()); - } - let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config")); - - // Test whether we're cross-compiling LLVM. This is a pretty rare case - // currently where we're producing an LLVM for a different platform than - // what this build script is currently running on. - // - // In that case, there's no guarantee that we can actually run the target, - // so the build system works around this by giving us the LLVM_CONFIG for - // the host platform. This only really works if the host LLVM and target - // LLVM are compiled the same way, but for us that's typically the case. - // - // We *want* detect this cross compiling situation by asking llvm-config - // what its host-target is. If that's not the TARGET, then we're cross - // compiling. Unfortunately `llvm-config` seems either be buggy, or we're - // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will - // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This - // tricks us into thinking we're doing a cross build when we aren't, so - // havoc ensues. - // - // In any case, if we're cross compiling, this generally just means that we - // can't trust all the output of llvm-config because it might be targeted - // for the host rather than the target. As a result a bunch of blocks below - // are gated on `if !is_crossed` - let target = env::var("TARGET").expect("TARGET was not set"); - let host = env::var("HOST").expect("HOST was not set"); - let is_crossed = target != host; - let is_wine = is_crossed && target.contains("windows-msvc") && !host.contains("windows"); - - let optional_components = &[ - "x86", "arm", - "aarch64", - // "amdgpu", - // "avr", - // "m68k", - // "mips", - // "powerpc", - // "systemz", - // "jsbackend", - // "webassembly", - // "msp430", - // "sparc", - // "nvptx", - // "hexagon", - // "riscv", - // "bpf", - ]; - - let required_components = &[ - "ipo", - "bitreader", - "bitwriter", - // "linker", - "option", - // "asmparser", - "lto", - "debuginfopdb", - "windowsmanifest", - "libdriver", // "coverage", - // "instrumentation", - ]; - - let components = output(Command::new(&llvm_config).arg("--components")); - let mut components = components.split_whitespace().collect::>(); - components.retain(|c| optional_components.contains(c) || required_components.contains(c)); - - for component in required_components { - if !components.contains(component) { - panic!("require llvm component {} but wasn't found", component); - } - } - - for component in components.iter() { - println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); - } - - // Link in our own LLVM shims, compiled with the same flags as LLVM - let mut cmd = Command::new(&llvm_config); - cmd.arg("--cxxflags"); - let cxxflags = output(&mut cmd); - - // Obtain version and pass as env variable - let mut cmd = Command::new(&llvm_config); - cmd.arg("--version"); - let version = output(&mut cmd).trim().to_owned(); - let version_components: Vec<_> = version.split('.').collect(); - if let [major, minor, patch] = version_components.as_slice() { - let major: Result = major.parse(); - let minor: Result = minor.parse(); - let patch: Result = patch.parse(); - if let (Ok(major), Ok(minor), Ok(patch)) = (major, minor, patch) { - println!("cargo:rustc-env=LLVM_VERSION_MAJOR={}", major); - println!("cargo:rustc-env=LLVM_VERSION_MINOR={}", minor); - println!("cargo:rustc-env=LLVM_VERSION_PATCH={}", patch); - } else { - fail(&format!( - "Invalid LLVM version {:?}!\nExpected 3 numbers separated by '.' foound {:?}", - version, components - )) - } - } else { - fail(&format!("Invalid LLVM version {:?}!\nExpected 3 components (major, minor, path) but found the following {} components\n{:?}", version, components.len(),components)) - } - - let mut cfg = cc::Build::new(); - cfg.warnings(false); - for flag in cxxflags.split_whitespace() { - // Ignore flags like `-m64` when we're doing a cross build - if is_crossed && flag.starts_with("-m") { - continue; - } - - if flag.starts_with("-flto") { - continue; - } - - // -Wdate-time is not supported by the netbsd cross compiler - if is_crossed && target.contains("netbsd") && flag.contains("date-time") { - continue; - } - - // Include path contains host directory, replace it with target - if is_crossed && flag.starts_with("-I") { - cfg.flag(&flag.replace(&host, &target)); - continue; - } - - cfg.flag(flag); - } - - for component in &components { - let mut flag = String::from("LLVM_COMPONENT_"); - flag.push_str(&component.to_uppercase()); - cfg.define(&flag, None); - } - - // if tracked_env_var_os("LLVM_RUSTLLVM").is_some() { - // cfg.define("LLVM_RUSTLLVM", None); - // } - - // if tracked_env_var_os("LLVM_NDEBUG").is_some() { - cfg.define("NDEBUG", None); - cfg.debug(false); - // } - - rerun_if_changed_anything_in_dir(Path::new("wrapper")); - cfg.cpp(true) - .warnings(true) - .file("wrapper/OpenVafWrapper.cpp") - .cpp_link_stdlib(None) // we handle this below - .compile("llvm-wrapper"); - - let (llvm_kind, llvm_link_arg) = detect_llvm_link(); - - // Link in all LLVM libraries, if we're using the "wrong" llvm-config then - // we don't pick up system libs because unfortunately they're for the host - // of llvm-config, not the target that we're attempting to link. - let mut cmd = Command::new(&llvm_config); - cmd.arg(llvm_link_arg).arg("--libnames"); - cmd.args(&components); - - for mut lib in output(&mut cmd).split_whitespace() { - lib = lib - .trim_end_matches(".lib") - .trim_end_matches(".so") - .trim_end_matches(".a") - .trim_start_matches("lib"); - - // Don't need or want this library, but LLVM's CMake build system - // doesn't provide a way to disable it, so filter it here even though we - // may or may not have built it. We don't reference anything from this - // library and it otherwise may just pull in extra dependencies on - // libedit which we don't want - if lib.contains("LLVMLineEditor") { - continue; - } - - println!("cargo:rustc-link-lib={llvm_kind}={}", lib); - } - - // Link in all LLVM libraries, if we're using the "wrong" llvm-config then - // we don't pick up system libs because unfortunately they're for the host - // of llvm-config, not the target that we're attempting to link. - let mut cmd = Command::new(&llvm_config); - cmd.arg(llvm_link_arg); - - if !is_crossed { - cmd.arg("--system-libs"); - cmd.args(&components); - - for lib in output(&mut cmd).split_whitespace() { - let name = if let Some(stripped) = lib.strip_prefix("-l") { - stripped - } else if let Some(stripped) = lib.strip_prefix('-') { - stripped - } else if Path::new(lib).exists() { - // On MSVC llvm-config will print the full name to libraries, but - // we're only interested in the name part - let name = Path::new(lib).file_name().unwrap().to_str().unwrap(); - name.trim_end_matches(".lib") - } else if lib.ends_with(".lib") { - // Some MSVC libraries just come up with `.lib` tacked on, so chop - // that off - lib.trim_end_matches(".lib") - } else { - continue; - }; - - println!("cargo:rustc-link-lib=dylib={}", name); - } - } else if target.contains("windows-gnu") { - println!("cargo:rustc-link-lib=shell32"); - println!("cargo:rustc-link-lib=uuid"); - } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") { - println!("cargo:rustc-link-lib=z"); - } - - // LLVM ldflags - // - // If we're a cross-compile of LLVM then unfortunately we can't trust these - // ldflags (largely where all the LLVM libs are located). Currently just - // hack around this by replacing the host triple with the target and pray - // that those -L directories are the same! - let mut cmd = Command::new(&llvm_config); - let mut libdir = output(cmd.arg(llvm_link_arg).arg("--libdir")); - - if is_wine { - libdir = winepath(&libdir).to_str().expect("all paths are valid utf-8").to_owned(); - } - - println!("cargo:rustc-link-search=native={}", libdir); - - let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS"); - if let Some(s) = llvm_linker_flags { - for lib in s.into_string().unwrap().split_whitespace() { - if let Some(stripped) = lib.strip_prefix("-l") { - println!("cargo:rustc-link-lib={}", stripped); - } else if let Some(stripped) = lib.strip_prefix("-L") { - println!("cargo:rustc-link-search=native={}", stripped); - } - } - } - - let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP"); - let llvm_use_libcxx = tracked_env_var_os("LLVM_USE_LIBCXX"); - - let stdcppname = if target.contains("openbsd") { - if target.contains("sparc64") { - "estdc++" - } else { - "c++" - } - } else if target.contains("freebsd") || target.contains("darwin") { - "c++" - } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() { - // NetBSD uses a separate library when relocation is required - "stdc++_pic" - } else if llvm_use_libcxx.is_some() { - "c++" - } else { - "stdc++" - }; - - // RISC-V GCC erroneously requires libatomic for sub-word - // atomic operations. FreeBSD uses Clang as its system - // compiler and provides no libatomic in its base system so - // does not want this. - if !target.contains("freebsd") && target.starts_with("riscv") { - println!("cargo:rustc-link-lib=atomic"); - } - - // C++ runtime library - if !target.contains("msvc") { - if let Some(s) = llvm_static_stdcpp { - assert!(!cxxflags.contains("stdlib=libc++")); - let path = PathBuf::from(s); - println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display()); - if target.contains("windows") { - println!("cargo:rustc-link-lib=static:-bundle={}", stdcppname); - } else { - println!("cargo:rustc-link-lib=static={}", stdcppname); - } - } else if cxxflags.contains("stdlib=libc++") { - println!("cargo:rustc-link-lib=c++"); - } else { - println!("cargo:rustc-link-lib={}", stdcppname); - } - } - - // Libstdc++ depends on pthread which Rust doesn't link on MinGW - // since nothing else requires it. - if target.contains("windows-gnu") { - println!("cargo:rustc-link-lib=static:-bundle=pthread"); - } -} diff --git a/openvaf/llvm/src/attributes.rs b/openvaf/llvm/src/attributes.rs deleted file mode 100644 index e93030b..0000000 --- a/openvaf/llvm/src/attributes.rs +++ /dev/null @@ -1,34 +0,0 @@ -use libc::c_char; - -/** - * Create a string attribute. - */ -use crate::{Attribute, Context, Value}; - -extern "C" { - fn LLVMCreateStringAttribute( - ctx: &Context, - key: *const c_char, - key_len: u32, - val: *const c_char, - val_len: u32, - ) -> &Attribute; - - pub fn LLVMPurgeAttrs(val: &Value); -} - -pub fn create_attr_string_value<'ll>( - llcx: &'ll Context, - attr: &str, - value: &str, -) -> &'ll Attribute { - unsafe { - LLVMCreateStringAttribute( - llcx, - attr.as_ptr().cast(), - attr.len().try_into().unwrap(), - value.as_ptr().cast(), - value.len().try_into().unwrap(), - ) - } -} diff --git a/openvaf/llvm/src/basic_block.rs b/openvaf/llvm/src/basic_block.rs deleted file mode 100644 index 696c4c3..0000000 --- a/openvaf/llvm/src/basic_block.rs +++ /dev/null @@ -1,37 +0,0 @@ -use libc::c_char; - -use crate::{BasicBlock, Context, Value}; - -// Core->Basic Block -extern "C" { - // pub fn LLVMBasicBlockAsValue(BB: &BasicBlock) -> &'a Value; - // pub fn LLVMValueIsBasicBlock(Val: &'a Value) -> LLVMBool; - // pub fn LLVMValueAsBasicBlock(Val: &'a Value) -> & BasicBlock; - // - /// Get the string name of a basic block. - // pub fn LLVMGetBasicBlockName(BB: & BasicBlock) -> *const ::libc::c_char; - // pub fn LLVMGetBasicBlockParent(BB: & BasicBlock) -> &'a Value; - // pub fn LLVMGetBasicBlockTerminator(BB: & BasicBlock) -> &'a Value; - // pub fn LLVMCountBasicBlocks(Fn: &'a Value) -> ::libc::c_uint; - // pub fn LLVMGetBasicBlocks(Fn: &'a Value, BasicBlocks: *mut & BasicBlock); - pub fn LLVMGetFirstBasicBlock(fun: &Value) -> &BasicBlock; - // pub fn LLVMGetLastBasicBlock(Fn: &'a Value) -> & BasicBlock; - // pub fn LLVMGetNextBasicBlock(BB: & BasicBlock) -> & BasicBlock; - // pub fn LLVMGetPreviousBasicBlock(BB: & BasicBlock) -> & BasicBlock; - // pub fn LLVMGetEntryBasicBlock(Fn: &'a Value) -> & BasicBlock; - /// Insert the given basic block after the insertion point of the given builder. - // pub fn LLVMInsertExistingBasicBlockAfterInsertBlock( - // Builder: LLVMBuilderRef, - // BB: & BasicBlock, - // ); - /// Append the given basic block to the basic block list of the given function. - // pub fn LLVMAppendExistingBasicBlock(Fn: &'a Value, BB: & BasicBlock); - pub fn LLVMAppendBasicBlockInContext<'a>( - ctx: &'a Context, - fun: &'a Value, - Name: *const c_char, - ) -> &'a BasicBlock; - - pub fn LLVMGetLastInstruction<'a>(bb: &'a BasicBlock) -> Option<&'a Value>; - -} diff --git a/openvaf/llvm/src/bitcode.rs b/openvaf/llvm/src/bitcode.rs deleted file mode 100644 index 2fa37b5..0000000 --- a/openvaf/llvm/src/bitcode.rs +++ /dev/null @@ -1,19 +0,0 @@ -use libc::{c_char, size_t}; - -use crate::{Bool, Context, MemoryBuffer, Module, Value}; - -extern "C" { - pub fn LLVMCreateMemoryBufferWithMemoryRange( - input: *const c_char, - input_len: size_t, - name: *const c_char, - requires_null_term: Bool, - ) -> &'static MemoryBuffer; - pub fn LLVMParseBitcodeInContext2<'a>( - ctx: &'a Context, - buf: &MemoryBuffer, - dst_module: &mut Option<&'a Module>, - ) -> Bool; - - pub fn LLVMGetNamedFunction<'a>(module: &'a Module, name: *const c_char) -> Option<&'a Value>; -} diff --git a/openvaf/llvm/src/builder.rs b/openvaf/llvm/src/builder.rs deleted file mode 100644 index 91544bb..0000000 --- a/openvaf/llvm/src/builder.rs +++ /dev/null @@ -1,419 +0,0 @@ -use ::libc::{c_char, c_uint}; -pub use LLVMBuildInBoundsGEP2 as LLVMBuildGEP2; - -use crate::{BasicBlock, Bool, Builder, Context, IntPredicate, RealPredicate, Type, Value}; - -// Core->Instruction Builders -extern "C" { - pub fn LLVMCreateBuilderInContext(ctx: &Context) -> &mut Builder<'_>; - pub fn LLVMPositionBuilderAtEnd<'a>(builder: &Builder<'a>, block: &'a BasicBlock); - pub fn LLVMPositionBuilder<'a>( - builder: &Builder<'a>, - block: &'a BasicBlock, - inst: Option<&'a Value>, - ); - pub fn LLVMGetInsertBlock<'a>(builder: &Builder<'a>) -> &'a BasicBlock; - pub fn LLVMDisposeBuilder<'a>(builder: &'a mut Builder<'a>); - - // Terminators - pub fn LLVMBuildRetVoid<'a>(builder: &Builder<'a>) -> &'a Value; - pub fn LLVMBuildRet<'a>(builder: &Builder<'a>, val: &'a Value) -> &'a Value; - pub fn LLVMBuildSwitch<'a>( - builder: &Builder<'a>, - val: &'a Value, - default_block: &'a BasicBlock, - num_case: c_uint, - ) -> &'a Value; - - pub fn LLVMAddCase<'a>(switch: &'a Value, val: &'a Value, bb: &'a BasicBlock); - - // pub fn LLVMBuildAggregateRet( - // builder: &Builder<'a>, - // RetVals: *mut &'a Value, - // N: ::libc::c_uint, - // ) -> &'a Value; - pub fn LLVMBuildBr<'a>(builder: &Builder<'a>, dst: &'a BasicBlock) -> &'a Value; - pub fn LLVMBuildCondBr<'a>( - builder: &Builder<'a>, - cond: &'a Value, - then_bb: &'a BasicBlock, - else_bb: &'a BasicBlock, - ) -> &'a Value; - - pub fn LLVMBuildExtractValue<'a>( - arg1: &Builder<'a>, - AggVal: &'a Value, - Index: c_uint, - Name: *const c_char, - ) -> &'a Value; - - // Arithmetic - pub fn LLVMBuildAdd<'a>( - arg1: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFAdd<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildSub<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFSub<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildMul<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildFMul<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildSDiv<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFDiv<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildSRem<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFRem<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildShl<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildLShr<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildAShr<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildAnd<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildOr<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildXor<'a>( - builder: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - // pub fn LLVMBuildBinOp<'a>( - // B: &Builder<'a>, - // Op: Opcode, - // LHS: &'a Value, - // RHS: &'a Value, - // Name: *const c_char, - // ) -> &'a Value; - pub fn LLVMBuildNeg<'a>(builder: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFNeg<'a>(builder: &Builder<'a>, V: &'a Value, Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNot<'a>(builder: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; - - // Memory - pub fn LLVMBuildMalloc<'a>( - builder: &Builder<'a>, - ty: &'a Type, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildArrayMalloc<'a>( - builder: &Builder<'a>, - ty: &'a Type, - len: &'a Value, - Name: *const c_char, - ) -> &'a Value; - // pub fn LLVMBuildMemSet( - // B: &Builder, - // Ptr: &'a Value, - // Val: &'a Value, - // Len: &'a Value, - // Align: ::libc::c_uint, - // ) -> &'a Value; - // pub fn LLVMBuildMemCpy( - // B: &Builder, - // Dst: &'a Value, - // DstAlign: ::libc::c_uint, - // Src: &'a Value, - // SrcAlign: ::libc::c_uint, - // Size: &'a Value, - // ) -> &'a Value; - // pub fn LLVMBuildMemMove( - // B: &Builder, - // Dst: &'a Value, - // DstAlign: ::libc::c_uint, - // Src: &'a Value, - // SrcAlign: ::libc::c_uint, - // Size: &'a Value, - // ) -> &'a Value; - pub fn LLVMBuildAlloca<'a>( - builder: &Builder<'a>, - ty: &'a Type, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildArrayAlloca<'a>( - builder: &Builder<'a>, - ty: &'a Type, - Val: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFree<'a>(builder: &Builder<'a>, PointerVal: &'a Value) -> &'a Value; - pub fn LLVMBuildLoad2<'a>( - builder: &Builder<'a>, - ty: &'a Type, - PointerVal: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildStore<'a>(builder: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - - // pub fn LLVMBuildGlobalString(B: &Builder, Str: *const c_char, Name: *const c_char) - // -> &'a Value; - // pub fn LLVMBuildGlobalStringPtr( - // B: &Builder, - // Str: *const c_char, - // Name: *const c_char, - // ) -> &'a Value; - - // Casts - // pub fn LLVMBuildTrunc( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildZExt( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildSExt( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildFPToUI( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildFPToSI( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - pub fn LLVMBuildUIToFP<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Destty: &'a Type, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildSIToFP<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Destty: &'a Type, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildInBoundsGEP2<'a>( - B: &Builder<'a>, - Ty: &'a Type, - Pointer: &'a Value, - Indices: *const &'a Value, - NumIndices: c_uint, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildStructGEP2<'a>( - builder: &Builder<'a>, - ty: &'a Type, - ptr: &'a Value, - idx: u32, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildSelect<'a>( - builder: &Builder<'a>, - cond: &'a Value, - then_val: &'a Value, - else_val: &'a Value, - name: *const c_char, - ) -> &'a Value; - // pub fn LLVMBuildFPTrunc( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildFPExt( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildPtrToInt( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildIntToPtr( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildBitCast( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildAddrSpaceCast( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildZExtOrBitCast( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildSExtOrBitCast( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildTruncOrBitCast( - // builder: &Builder<'a>, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - // pub fn LLVMBuildCast<'a>( - // B: &Builder, - // Op: Opcode, - // Val: &'a Value, - // Destty: &'a Type, - // Name: *const c_char, - // ) -> &'a Value; - pub fn LLVMBuildIntCast2<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Destty: &'a Type, - IsSigned: Bool, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFPCast<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Destty: &'a Type, - Name: *const c_char, - ) -> &'a Value; - - // Comparisons - pub fn LLVMBuildICmp<'a>( - builder: &Builder<'a>, - Op: IntPredicate, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildFCmp<'a>( - builder: &Builder<'a>, - Op: RealPredicate, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - - // Miscellaneous instructions - pub fn LLVMBuildPhi<'a>(builder: &Builder<'a>, ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildCall2<'a>( - builder: &Builder<'a>, - ty: &'a Type, - Fn: &'a Value, - Args: *const &'a Value, - NumArgs: c_uint, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildIsNull<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Name: *const c_char, - ) -> &'a Value; - pub fn LLVMBuildIsNotNull<'a>( - builder: &Builder<'a>, - Val: &'a Value, - Name: *const c_char, - ) -> &'a Value; - - pub fn LLVMBuildPtrDiff2<'a>( - builder: &Builder<'a>, - elem_ty: &'a Type, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char, - ) -> &'a Value; - - pub fn LVMBuildArrayMalloc<'a>( - builder: &Builder<'a>, - ty: &'a Type, - val: &'a Value, - Name: *const c_char, - ) -> &'a Value; -} diff --git a/openvaf/llvm/src/context.rs b/openvaf/llvm/src/context.rs deleted file mode 100644 index 9b54218..0000000 --- a/openvaf/llvm/src/context.rs +++ /dev/null @@ -1,22 +0,0 @@ -use libc::{c_char, c_void}; - -use crate::{Context, DiagnosticHandler, DiagnosticInfo, DiagnosticSeverity}; - -// Core -extern "C" { - // pub fn LLVMShutdown(); - pub fn LLVMCreateMessage(Message: *const c_char) -> *mut c_char; - pub fn LLVMDisposeMessage(Message: *mut c_char); - - pub fn LLVMContextCreate() -> &'static mut Context; - pub fn LLVMContextDispose(ctx: &'static mut Context); - - pub fn LLVMContextSetDiagnosticHandler( - ctx: &Context, - handler: DiagnosticHandler, - diagnostic_ctx: *mut c_void, - ); - - pub fn LLVMGetDiagInfoDescription(info: &DiagnosticInfo) -> *const c_char; - pub fn LLVMGetDiagInfoSeverity(info: &DiagnosticInfo) -> DiagnosticSeverity; -} diff --git a/openvaf/llvm/src/initialization.rs b/openvaf/llvm/src/initialization.rs deleted file mode 100644 index ef012e5..0000000 --- a/openvaf/llvm/src/initialization.rs +++ /dev/null @@ -1,263 +0,0 @@ -//! Initialization routines which must be called before using library features. - -use std::ffi::CString; -use std::sync::Once; - -use ahash::AHashSet; -use libc::{c_char, c_int}; - -use crate::{Bool, PassRegistry}; - -extern "C" { - fn LLVMInitializeCore(R: *mut PassRegistry); - fn LLVMInitializeTransformUtils(R: *mut PassRegistry); - fn LLVMInitializeScalarOpts(R: *mut PassRegistry); - fn LLVMInitializeVectorization(R: *mut PassRegistry); - fn LLVMInitializeInstCombine(R: *mut PassRegistry); - // fn LLVMInitializeAggressiveInstCombiner(R: *mut PassRegistry); - fn LLVMInitializeIPO(R: *mut PassRegistry); - fn LLVMInitializeAnalysis(R: *mut PassRegistry); - fn LLVMInitializeCodeGen(R: *mut PassRegistry); - fn LLVMInitializeTarget(R: *mut PassRegistry); - - fn LLVMGetGlobalPassRegistry() -> *mut PassRegistry; - fn LLVMIsMultithreaded() -> Bool; - fn LLVMParseCommandLineOptions( - argc: c_int, - argv: *const *const c_char, - overview: *const c_char, - ); -} - -static INIT: Once = Once::new(); - -pub fn init(cg_opts: &[String], tg_opts: &[String]) { - unsafe { - // Before we touch LLVM, make sure that multithreading is enabled. - if LLVMIsMultithreaded() != 1 { - panic!("LLVM compiled without support for threads"); - } - INIT.call_once(|| { - configure_llvm(cg_opts, tg_opts); - }); - } -} - -pub fn require_inited() { - if !INIT.is_completed() { - panic!("LLVM is not initialized"); - } -} - -unsafe fn configure_llvm(cg_opts: &[String], tg_opts: &[String]) { - let n_args = cg_opts.len() + tg_opts.len(); - let mut llvm_c_strs = Vec::with_capacity(n_args + 1); - let mut llvm_args = Vec::with_capacity(n_args + 1); - - fn llvm_arg_to_arg_name(full_arg: &str) -> &str { - full_arg.trim().split(|c: char| c == '=' || c.is_whitespace()).next().unwrap_or("") - } - - let args = cg_opts.iter().chain(tg_opts.iter()); - - let user_specified_args: AHashSet<_> = - args.clone().map(|s| llvm_arg_to_arg_name(s)).filter(|s| !s.is_empty()).collect(); - - { - // This adds the given argument to LLVM. Unless `force` is true - // user specified arguments are *not* overridden. - let mut add = |arg: &str, force: bool| { - if force || !user_specified_args.contains(llvm_arg_to_arg_name(arg)) { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); - } - }; - - // Set the llvm "program name" to make usage and invalid argument messages more clear. - add(concat!(env!("COMPILER_NAME"), " -Cllvm-args=\"...\" with"), true); - add("-time-passes", false); - for arg in args { - add(arg, true); - } - } - - // if sess.opts.debugging_opts.llvm_time_trace { - // llvm::LLVMTimeTraceProfilerInitialize(); - // } - - let registry = LLVMGetGlobalPassRegistry(); - LLVMInitializeCore(registry); - LLVMInitializeCodeGen(registry); - LLVMInitializeScalarOpts(registry); - LLVMInitializeVectorization(registry); - LLVMInitializeIPO(registry); - LLVMInitializeAnalysis(registry); - LLVMInitializeTransformUtils(registry); - LLVMInitializeInstCombine(registry); - LLVMInitializeTarget(registry); - - initialize_available_targets(); - - LLVMParseCommandLineOptions( - llvm_args.len() as c_int, - llvm_args.as_ptr(), - b"A Verilog-A compiler".as_ptr() as *const c_char, - ); -} - -/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`. -/// N.B., this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s. -pub fn initialize_available_targets() { - macro_rules! init_target( - ($cfg:meta, $($method:ident),*) => { { - #[cfg($cfg)] - fn init() { - extern "C" { - $(fn $method();)* - } - unsafe { - $($method();)* - } - } - #[cfg(not($cfg))] - fn init() { } - init(); - } } - ); - - // Currently the only supported targets are x86, arm, aarch64 and riscv - init_target!( - llvm_component = "x86", - LLVMInitializeX86TargetInfo, - LLVMInitializeX86Target, - LLVMInitializeX86TargetMC, - LLVMInitializeX86AsmPrinter, - LLVMInitializeX86AsmParser - ); - init_target!( - llvm_component = "arm", - LLVMInitializeARMTargetInfo, - LLVMInitializeARMTarget, - LLVMInitializeARMTargetMC, - LLVMInitializeARMAsmPrinter, - LLVMInitializeARMAsmParser - ); - init_target!( - llvm_component = "aarch64", - LLVMInitializeAArch64TargetInfo, - LLVMInitializeAArch64Target, - LLVMInitializeAArch64TargetMC, - LLVMInitializeAArch64AsmPrinter, - LLVMInitializeAArch64AsmParser - ); - // init_target!( - // llvm_component = "amdgpu", - // LLVMInitializeAMDGPUTargetInfo, - // LLVMInitializeAMDGPUTarget, - // LLVMInitializeAMDGPUTargetMC, - // LLVMInitializeAMDGPUAsmPrinter, - // LLVMInitializeAMDGPUAsmParser - // ); - // init_target!( - // llvm_component = "avr", - // LLVMInitializeAVRTargetInfo, - // LLVMInitializeAVRTarget, - // LLVMInitializeAVRTargetMC, - // LLVMInitializeAVRAsmPrinter, - // LLVMInitializeAVRAsmParser - // ); - // init_target!( - // llvm_component = "m68k", - // LLVMInitializeM68kTargetInfo, - // LLVMInitializeM68kTarget, - // LLVMInitializeM68kTargetMC, - // LLVMInitializeM68kAsmPrinter, - // LLVMInitializeM68kAsmParser - // ); - // init_target!( - // llvm_component = "mips", - // LLVMInitializeMipsTargetInfo, - // LLVMInitializeMipsTarget, - // LLVMInitializeMipsTargetMC, - // LLVMInitializeMipsAsmPrinter, - // LLVMInitializeMipsAsmParser - // ); - // init_target!( - // llvm_component = "powerpc", - // LLVMInitializePowerPCTargetInfo, - // LLVMInitializePowerPCTarget, - // LLVMInitializePowerPCTargetMC, - // LLVMInitializePowerPCAsmPrinter, - // LLVMInitializePowerPCAsmParser - // ); - // init_target!( - // llvm_component = "systemz", - // LLVMInitializeSystemZTargetInfo, - // LLVMInitializeSystemZTarget, - // LLVMInitializeSystemZTargetMC, - // LLVMInitializeSystemZAsmPrinter, - // LLVMInitializeSystemZAsmParser - // ); - // init_target!( - // llvm_component = "jsbackend", - // LLVMInitializeJSBackendTargetInfo, - // LLVMInitializeJSBackendTarget, - // LLVMInitializeJSBackendTargetMC - // ); - // init_target!( - // llvm_component = "msp430", - // LLVMInitializeMSP430TargetInfo, - // LLVMInitializeMSP430Target, - // LLVMInitializeMSP430TargetMC, - // LLVMInitializeMSP430AsmPrinter, - // LLVMInitializeMSP430AsmParser - // ); - init_target!( - llvm_component = "riscv", - LLVMInitializeRISCVTargetInfo, - LLVMInitializeRISCVTarget, - LLVMInitializeRISCVTargetMC, - LLVMInitializeRISCVAsmPrinter, - LLVMInitializeRISCVAsmParser - ); - // init_target!( - // llvm_component = "sparc", - // LLVMInitializeSparcTargetInfo, - // LLVMInitializeSparcTarget, - // LLVMInitializeSparcTargetMC, - // LLVMInitializeSparcAsmPrinter, - // LLVMInitializeSparcAsmParser - // ); - // init_target!( - // llvm_component = "nvptx", - // LLVMInitializeNVPTXTargetInfo, - // LLVMInitializeNVPTXTarget, - // LLVMInitializeNVPTXTargetMC, - // LLVMInitializeNVPTXAsmPrinter - // ); - // init_target!( - // llvm_component = "hexagon", - // LLVMInitializeHexagonTargetInfo, - // LLVMInitializeHexagonTarget, - // LLVMInitializeHexagonTargetMC, - // LLVMInitializeHexagonAsmPrinter, - // LLVMInitializeHexagonAsmParser - // ); - // init_target!( - // llvm_component = "webassembly", - // LLVMInitializeWebAssemblyTargetInfo, - // LLVMInitializeWebAssemblyTarget, - // LLVMInitializeWebAssemblyTargetMC, - // LLVMInitializeWebAssemblyAsmPrinter, - // LLVMInitializeWebAssemblyAsmParser - // ); - // init_target!( - // llvm_component = "bpf", - // LLVMInitializeBPFTargetInfo, - // LLVMInitializeBPFTarget, - // LLVMInitializeBPFTargetMC, - // LLVMInitializeBPFAsmPrinter, - // LLVMInitializeBPFAsmParser - // ); -} diff --git a/openvaf/llvm/src/lib.rs b/openvaf/llvm/src/lib.rs deleted file mode 100644 index 1af30fb..0000000 --- a/openvaf/llvm/src/lib.rs +++ /dev/null @@ -1,366 +0,0 @@ -#![allow(non_camel_case_types)] -#![allow(non_upper_case_globals)] - -//! Bindings to LLVM's C API. -//! -//! Refer to the [LLVM documentation](http://llvm.org/docs/) for more -//! information. -//! -//! This is a vendored version of [llvm-sys](https://gitlab.com/taricorp/llvm-sys.rs) -//! adjusted to fit the needs of this project. Furthermore some improvements to llvm made in rustc -//! have been copied here. -//! -//! The buildscript from llvm-sys is replaced with the one from rustc_llvm to allow for faster -//! compile times (no regex/lazy static), cross compilation and dynamic linking -//! -//! Furthermore the types/functions exported here are reduced to only those actually used in OpenVAF to -//! further improve compile times - -use std::fmt; - -use libc::{c_char, c_uint, c_void}; - -use crate::util::InvariantOpaque; - -mod util; - -pub mod attributes; -pub mod basic_block; -pub mod bitcode; -pub mod builder; -pub mod context; -pub mod initialization; -// pub mod lld; -pub mod module; -pub mod pass_manager; -pub mod support; -pub mod targets; -pub mod types; -pub mod values; - -pub use attributes::*; -pub use basic_block::*; -pub use bitcode::*; -pub use builder::*; -pub use context::*; -pub use initialization::*; -pub use module::*; -pub use pass_manager::*; -pub use targets::*; -pub use types::*; -pub use values::*; - -pub type Bool = c_uint; -pub const True: Bool = 1; -pub const False: Bool = 0; - -// Opaque pointer types -// TODO move to opaqute times when stabilized -// BLOCK https://github.com/rust-lang/rust/issues/43467 - -pub enum MemoryBuffer {} - -impl fmt::Debug for MemoryBuffer { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum Context {} - -impl fmt::Debug for Context { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -#[repr(C)] -pub struct Builder<'a>(InvariantOpaque<'a>); - -#[repr(C)] -pub struct PassManager<'a>(InvariantOpaque<'a>); - -pub enum Type {} - -impl fmt::Debug for Type { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum Value {} - -impl fmt::Debug for Value { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum Attribute {} - -impl fmt::Debug for Attribute { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum BasicBlock {} - -impl fmt::Debug for BasicBlock { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum Module {} - -impl fmt::Debug for Module { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum PassRegistry {} - -impl fmt::Debug for PassRegistry { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum PassManagerBuilder {} - -impl fmt::Debug for PassManagerBuilder { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -pub enum Target {} - -impl fmt::Debug for Target { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} -pub enum DiagnosticInfo {} - -impl fmt::Debug for DiagnosticInfo { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -#[derive(Debug)] -pub enum TargetData {} - -#[derive(Debug)] -pub enum TargetMachine {} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum OptLevel { - None = 0, - Less = 1, - Default = 2, - Aggressive = 3, -} - -// Only allow default CodeModel/RelocMode -// If we allow different modes we might need to change -// this for each module as done in rustc - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum RelocMode { - Default = 0, - // Static = 1, - PIC = 2, - // DynamicNoPic = 3, - // ROPI = 4, - // RWPI = 5, - // ROPI_RWPI = 6, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum CodeModel { - Default = 0, - // JITDefault = 1, - // Tiny = 2, - // Small = 3, - // Kernel = 4, - // Medium = 5, - // Large = 6, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum CodeGenFileType { - AssemblyFile = 0, - ObjectFile = 1, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Linkage { - ExternalLinkage = 0, - AvailableExternallyLinkage = 1, - LinkOnceAnyLinkage = 2, - LinkOnceODRLinkage = 3, - LinkOnceODRAutoHideLinkage = 4, - WeakAnyLinkage = 5, - WeakODRLinkage = 6, - AppendingLinkage = 7, - Internal = 8, - PrivateLinkage = 9, - DLLImportLinkage = 10, - DLLExportLinkage = 11, - ExternalWeakLinkage = 12, - GhostLinkage = 13, - CommonLinkage = 14, - LinkerPrivateLinkage = 15, - LinkerPrivateWeakLinkage = 16, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Visibility { - Default = 0, - Hidden = 1, - Protected = 2, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum UnnamedAddr { - /// Address of the GV is significant. - No, - /// Address of the GV is locally insignificant. - Local, - /// Address of the GV is globally insignificant. - Global, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum DLLStorageClass { - Default = 0, - Import = 1, - Export = 2, -} - -// LLVM CallingConv::ID. Should we wrap this? -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -#[repr(C)] -pub enum CallConv { - CCallConv = 0, - FastCallConv = 8, - ColdCallConv = 9, - // X86StdcallCallConv = 64, - // X86FastcallCallConv = 65, - // ArmAapcsCallConv = 67, - // Msp430Intr = 69, - // X86_ThisCall = 70, - // PtxKernel = 71, - // X86_64_SysV = 78, - // X86_64_Win64 = 79, - // X86_VectorCall = 80, - // X86_Intr = 83, - // AvrNonBlockingInterrupt = 84, - // AvrInterrupt = 85, - // AmdGpuKernel = 91, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum IntPredicate { - IntEQ = 32, - IntNE = 33, - IntUGT = 34, - IntUGE = 35, - IntULT = 36, - IntULE = 37, - IntSGT = 38, - IntSGE = 39, - IntSLT = 40, - IntSLE = 41, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)] -pub enum DiagnosticSeverity { - Error = 0, - Warning = 1, - Remark = 2, - Note = 3, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum RealPredicate { - RealPredicateFalse = 0, - RealOEQ = 1, - RealOGT = 2, - RealOGE = 3, - RealOLT = 4, - RealOLE = 5, - RealONE = 6, - RealORD = 7, - RealUNO = 8, - RealUEQ = 9, - RealUGT = 10, - RealUGE = 11, - RealULT = 12, - RealULE = 13, - RealUNE = 14, - RealPredicateTrue = 15, -} - -pub const LLVMAttributeReturnIndex: ::libc::c_uint = 0; -pub const LLVMAttributeFunctionIndex: ::libc::c_uint = !0; // -1 -/// Either LLVMAttributeReturnIndex, LLVMAttributeFunctionIndex, or a parameter -/// number from 1 to N. -pub type LLVMAttributeIndex = ::libc::c_uint; - -pub type DiagnosticHandler = Option; -pub type LLVMYieldCallback = Option; - -pub fn get_version() -> (u32, u32, u32) { - // If RUST_CHECK is set we do not link LLVM and the version is not known, just use dummy values in that case - ( - option_env!("LLVM_VERSION_MAJOR").map_or(14, |it| it.parse().unwrap()), - option_env!("LLVM_VERSION_MINOR").map_or(0, |it| it.parse().unwrap()), - option_env!("LLVM_VERSION_PATCH").map_or(6, |it| it.parse().unwrap()), - ) -} - -/// Empty string, to be used where LLVM expects an instruction name, indicating -/// that the instruction is to be left unnamed (i.e. numbered, in textual IR). -// FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer. -pub const UNNAMED: *const c_char = b"\0".as_ptr() as *const c_char; - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum TypeKind { - Void = 0, - Half = 1, - Float = 2, - Double = 3, - X86_FP80 = 4, - FP128 = 5, - PPC_FP128 = 6, - Label = 7, - Integer = 8, - Function = 9, - Struct = 10, - Array = 11, - Pointer = 12, - Vector = 13, - Metadata = 14, - X86_MMX = 15, - Token = 16, - ScalableVector = 17, - BFloat = 18, - X86_AMX = 19, -} diff --git a/openvaf/llvm/src/module.rs b/openvaf/llvm/src/module.rs deleted file mode 100644 index 4798c88..0000000 --- a/openvaf/llvm/src/module.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::iter; -use std::mem::MaybeUninit; - -use libc::{c_char, size_t}; - -use crate::support::LLVMString; -use crate::{Bool, Context, Module, Type, Value}; - -// Core->Modules -extern "C" { - pub fn LLVMModuleCreateWithNameInContext<'a>( - ModuleID: *const c_char, - C: &'a Context, - ) -> &'a Module; - - /// Set the original source file name of a module to a string Name with length Len. - pub fn LLVMSetSourceFileName(module: &Module, name: *const c_char, len: size_t); - - pub fn LLVMSetDataLayout(module: &Module, DataLayoutStr: *const c_char); - pub fn LLVMLinkModules2(dst: &Module, src: &Module) -> Bool; - // /// Returns the module flags as an array of flag-key-value triples. The caller is responsible for freeing this array by calling LLVMDisposeModuleFlagsMetadata. - // pub fn LLVMCopyModuleFlagsMetadata( - // module: &Module, - // Len: *mut size_t, - // ) -> *mut LLVMModuleFlagEntry; - // /// Destroys module flags metadata entries. - // pub fn LLVMDisposeModuleFlagsMetadata(Entries: *mut LLVMModuleFlagEntry); - // /// Returns the flag behavior for a module flag entry at a specific index. - // pub fn LLVMModuleFlagEntriesGetFlagBehavior( - // Entries: *mut LLVMModuleFlagEntry, - // Index: c_uint, - // ) -> LLVMModuleFlagBehavior; - // /// Returns the key for a module flag entry at a specific index. - // pub fn LLVMModuleFlagEntriesGetKey( - // Entries: *mut LLVMModuleFlagEntry, - // Index: c_uint, - // Len: *mut size_t, - // ) -> *const c_char; - // /// Returns the metadata for a module flag entry at a specific index. - // pub fn LLVMModuleFlagEntriesGetMetadata( - // Entries: *mut LLVMModuleFlagEntry, - // Index: c_uint, - // ) -> &'a Metadata; - // /// Add a module-level flag to the module-level flags metadata if it doesn't already exist. - // pub fn LLVMGetModuleFlag(module: &Module, Key: *const c_char, KeyLen: size_t) -> &'a Metadata; - // /// Add a module-level flag to the module-level flags metadata if it doesn't already exist. - // pub fn LLVMAddModuleFlag( - // module: &Module, - // Behavior: LLVMModuleFlagBehavior, - // Key: *const c_char, - // KeyLen: size_t, - // Val: &'a Metadata, - // ); - - // pub fn LLVMDumpModule(module: &Module); - pub fn LLVMPrintModuleToString(module: &Module) -> *mut c_char; - - // pub fn LLVMGetModuleInlineAsm(module: &Module, Len: *mut size_t) -> *const c_char; - // pub fn LLVMSetModuleInlineAsm2(module: &Module, Asm: *const c_char, Len: size_t); - // pub fn LLVMAppendModuleInlineAsm(module: &Module, Asm: *const c_char, Len: size_t); - // pub fn LLVMGetInlineAsm( - // Ty: TypeRef, - // AsmString: *mut c_char, - // AsmStringSize: size_t, - // Constraints: *mut c_char, - // ConstraintsSize: size_t, - // HasSideEffects: LLVMBool, - // IsAlignStack: LLVMBool, - // Dialect: LLVMInlineAsmDialect, - // CanThrow: LLVMBool, - // ) -> &'a Value; - - // // pub fn LLVMGetModuleContext(module: &Module) -> &'a Context; - // pub fn LLVMGetFirstNamedMetadata(module: &Module) -> NamedMDNodeRef; - // pub fn LLVMGetLastNamedMetadata(module: &Module) -> NamedMDNodeRef; - // pub fn LLVMGetNextNamedMetadata(NamedMDNode: NamedMDNodeRef) -> NamedMDNodeRef; - // pub fn LLVMGetPreviousNamedMetadata(NamedMDNode: NamedMDNodeRef) -> NamedMDNodeRef; - // pub fn LLVMGetNamedMetadata( - // module: &Module, - // name: *const c_char, - // NameLen: size_t, - // ) -> NamedMDNodeRef; - // pub fn LLVMGetOrInsertNamedMetadata( - // module: &Module, - // name: *const c_char, - // NameLen: size_t, - // ) -> NamedMDNodeRef; - // pub fn LLVMGetNamedMetadataName( - // NamedMD: NamedMDNodeRef, - // NameLen: *const size_t, - // ) -> *const c_char; - // pub fn LLVMGetNamedMetadataNumOperands(module: &Module, name: *const c_char) -> c_uint; - // pub fn LLVMGetNamedMetadataOperands(module: &Module, name: *const c_char, Dest: *mut &'a Value); - // pub fn LLVMAddNamedMetadataOperand(module: &Module, name: *const c_char, Val: &'a Value); - // pub fn LLVMGetDebugLocDirectory(Val: &'a Value, Length: *mut c_uint) -> *const c_char; - // pub fn LLVMGetDebugLocFilename(Val: &'a Value, Length: *mut c_uint) -> *const c_char; - // pub fn LLVMGetDebugLocLine(Val: &'a Value) -> c_uint; - // pub fn LLVMGetDebugLocColumn(Val: &'a Value) -> c_uint; - pub fn LLVMAddFunction<'a>( - module: &'a Module, - name: *const c_char, - FunctionTy: &'a Type, - ) -> &'a Value; - // pub fn LLVMGetNamedFunction<'a>(module: &Module, name: *const c_char) -> &'a Value; - fn LLVMGetFirstFunction(module: &Module) -> Option<&Value>; - // fn LLVMGetLastFunction<'a>(module: &Module) -> Option<&'a Value>; - fn LLVMGetNextFunction(fun: &Value) -> Option<&Value>; - // fn LLVMGetPreviousFunction<'a>(Fn: &'a Value) -> Option<&'a Value>; - - /// Verify that a module is valid, taking the specified action if not. - /// - /// Optionally returns a human-readable description of any invalid constructs, - /// which must be disposed with `LLVMDisposeMessage`. - pub fn LLVMVerifyModule( - module: &Module, - Action: VerifierFailureAction, - OutMessage: Option<&mut MaybeUninit>, - ) -> Bool; - -} - -pub fn function_iter(module: &Module) -> impl Iterator + '_ { - let fun = unsafe { LLVMGetFirstFunction(module) }; - iter::successors(fun, |fun| unsafe { LLVMGetNextFunction(fun) }) -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum VerifierFailureAction { - /// Print to stderr and abort the process. - AbortProcess = 0, - /// Print to stderr and return 1. - PrintMessage = 1, - /// Return 1 and print nothing. - ReturnStatus = 2, -} diff --git a/openvaf/llvm/src/object.rs b/openvaf/llvm/src/object.rs deleted file mode 100644 index 0849f02..0000000 --- a/openvaf/llvm/src/object.rs +++ /dev/null @@ -1,162 +0,0 @@ -//! Object file reading and writing - -use super::prelude::*; - -#[derive(Debug)] -pub enum LLVMOpaqueSectionIterator {} - -pub type LLVMSectionIteratorRef = *mut LLVMOpaqueSectionIterator; - -#[derive(Debug)] -pub enum LLVMOpaqueSymbolIterator {} - -pub type LLVMSymbolIteratorRef = *mut LLVMOpaqueSymbolIterator; - -#[derive(Debug)] -pub enum LLVMOpaqueRelocationIterator {} - -pub type LLVMRelocationIteratorRef = *mut LLVMOpaqueRelocationIterator; - -#[derive(Debug)] -pub enum LLVMOpaqueBinary {} - -pub type LLVMBinaryRef = *mut LLVMOpaqueBinary; - -#[repr(C)] -#[derive(Debug)] -pub enum LLVMBinaryType { - /// Archive file - LLVMBinaryTypeArchive, - /// Mach-O Universal Binary file - LLVMBinaryTypeMachOUniversalBinary, - /// COFF Import file - LLVMBinaryTypeCOFFImportFile, - /// LLVM IR - LLVMBinaryTypeIR, - /// Windows resource (.res) file - LLVMBinaryTypeWinRes, - /// COFF Object file - LLVMBinaryTypeCOFF, - /// ELF 32-bit, little endian - LLVMBinaryTypeELF32L, - /// ELF 32-bit, big endian - LLVMBinaryTypeELF32B, - /// ELF 64-bit, little endian - LLVMBinaryTypeELF64L, - /// ELF 64-bit, big endian - LLVMBinaryTypeELF64B, - /// MachO 32-bit, little endian - LLVMBinaryTypeMachO32L, - /// MachO 32-bit, big endian - LLVMBinaryTypeMachO32B, - /// MachO 64-bit, little endian - LLVMBinaryTypeMachO64L, - /// MachO 64-bit, big endian - LLVMBinaryTypeMachO64B, - /// Web assembly - LLVMBinaryTypeWasm, -} - -#[deprecated(since = "LLVM 9.0")] -pub enum LLVMOpaqueObjectFile {} - -#[allow(deprecated)] -#[deprecated(since = "LLVM 9.0")] -pub type LLVMObjectFileRef = *mut LLVMOpaqueObjectFile; - -extern "C" { - /// Create a binary file from the given memory buffer. - pub fn LLVMCreateBinary( - MemBuf: LLVMMemoryBufferRef, - Context: LLVMContextRef, - ErrorMessage: *mut *mut ::libc::c_char, - ) -> LLVMBinaryRef; - /// Dispose of a binary file - pub fn LLVMDisposeBinary(BR: LLVMBinaryRef); - - pub fn LLVMBinaryCopyMemoryBuffer(BR: LLVMBinaryRef) -> LLVMMemoryBufferRef; - pub fn LLVMBinaryGetType(BR: LLVMBinaryRef) -> LLVMBinaryType; - pub fn LLVMMachOUniversalBinaryCopyObjectForArch( - BR: LLVMBinaryRef, - Arch: *const ::libc::c_char, - ArchLen: ::libc::size_t, - ErrorMessage: *mut *mut ::libc::c_char, - ) -> LLVMBinaryRef; - - pub fn LLVMObjectFileCopySectionIterator(BR: LLVMBinaryRef) -> LLVMSectionIteratorRef; - pub fn LLVMObjectFileIsSectionIteratorAtEnd( - BR: LLVMBinaryRef, - SI: LLVMSectionIteratorRef, - ) -> LLVMBool; - pub fn LLVMObjectFileCopySymbolIterator(BR: LLVMBinaryRef) -> LLVMSymbolIteratorRef; - pub fn LLVMObjectFileIsSymbolIteratorAtEnd( - BR: LLVMBinaryRef, - SI: LLVMSymbolIteratorRef, - ) -> LLVMBool; - pub fn LLVMDisposeSectionIterator(SI: LLVMSectionIteratorRef); - - pub fn LLVMMoveToNextSection(SI: LLVMSectionIteratorRef); - pub fn LLVMMoveToContainingSection(Sect: LLVMSectionIteratorRef, Sym: LLVMSymbolIteratorRef); - pub fn LLVMDisposeSymbolIterator(SI: LLVMSymbolIteratorRef); - pub fn LLVMMoveToNextSymbol(SI: LLVMSymbolIteratorRef); - pub fn LLVMGetSectionName(SI: LLVMSectionIteratorRef) -> *const ::libc::c_char; - pub fn LLVMGetSectionSize(SI: LLVMSectionIteratorRef) -> u64; - pub fn LLVMGetSectionContents(SI: LLVMSectionIteratorRef) -> *const ::libc::c_char; - pub fn LLVMGetSectionAddress(SI: LLVMSectionIteratorRef) -> u64; - pub fn LLVMGetSectionContainsSymbol( - SI: LLVMSectionIteratorRef, - Sym: LLVMSymbolIteratorRef, - ) -> LLVMBool; - pub fn LLVMGetRelocations(Section: LLVMSectionIteratorRef) -> LLVMRelocationIteratorRef; - pub fn LLVMDisposeRelocationIterator(RI: LLVMRelocationIteratorRef); - pub fn LLVMIsRelocationIteratorAtEnd( - Section: LLVMSectionIteratorRef, - RI: LLVMRelocationIteratorRef, - ) -> LLVMBool; - pub fn LLVMMoveToNextRelocation(RI: LLVMRelocationIteratorRef); - pub fn LLVMGetSymbolName(SI: LLVMSymbolIteratorRef) -> *const ::libc::c_char; - pub fn LLVMGetSymbolAddress(SI: LLVMSymbolIteratorRef) -> u64; - pub fn LLVMGetSymbolSize(SI: LLVMSymbolIteratorRef) -> u64; - pub fn LLVMGetRelocationOffset(RI: LLVMRelocationIteratorRef) -> u64; - pub fn LLVMGetRelocationSymbol(RI: LLVMRelocationIteratorRef) -> LLVMSymbolIteratorRef; - pub fn LLVMGetRelocationType(RI: LLVMRelocationIteratorRef) -> u64; - pub fn LLVMGetRelocationTypeName(RI: LLVMRelocationIteratorRef) -> *const ::libc::c_char; - pub fn LLVMGetRelocationValueString(RI: LLVMRelocationIteratorRef) -> *const ::libc::c_char; - - #[allow(deprecated)] - #[deprecated(since = "LLVM 9.0", note = "Use LLVMCreateBinary instead")] - pub fn LLVMCreateObjectFile(MemBuf: LLVMMemoryBufferRef) -> LLVMObjectFileRef; - #[allow(deprecated)] - #[deprecated(since = "LLVM 9.0", note = "Use LLVMDisposeBinary instead")] - pub fn LLVMDisposeObjectFile(ObjectFile: LLVMObjectFileRef); - #[allow(deprecated)] - #[deprecated( - since = "LLVM 9.0", - note = "Use LLVMObjectFileCopySectionIterator instead" - )] - pub fn LLVMGetSections(ObjectFile: LLVMObjectFileRef) -> LLVMSectionIteratorRef; - #[allow(deprecated)] - #[deprecated( - since = "LLVM 9.0", - note = "Use LLVMObjectFileIsSectionIteratorAtEnd instead" - )] - pub fn LLVMIsSectionIteratorAtEnd( - ObjectFile: LLVMObjectFileRef, - SI: LLVMSectionIteratorRef, - ) -> LLVMBool; - #[allow(deprecated)] - #[deprecated( - since = "LLVM 9.0", - note = "Use LLVMObjectFileCopySymbolIterator instead" - )] - pub fn LLVMGetSymbols(ObjectFile: LLVMObjectFileRef) -> LLVMSymbolIteratorRef; - #[allow(deprecated)] - #[deprecated( - since = "LLVM 9.0", - note = "Use LLVMObjectFileIsSymbolIteratorAtEnd instead" - )] - pub fn LLVMIsSymbolIteratorAtEnd( - ObjectFile: LLVMObjectFileRef, - SI: LLVMSymbolIteratorRef, - ) -> LLVMBool; -} diff --git a/openvaf/llvm/src/pass_manager.rs b/openvaf/llvm/src/pass_manager.rs deleted file mode 100644 index 56784e7..0000000 --- a/openvaf/llvm/src/pass_manager.rs +++ /dev/null @@ -1,82 +0,0 @@ -use libc::c_uint; - -use crate::module::function_iter; -use crate::util::InvariantOpaque; -use crate::{Bool, Module, OptLevel, PassManager, PassManagerBuilder, Value}; - -#[repr(C)] -pub struct FunctionPassManager<'a>(InvariantOpaque<'a>); - -extern "C" { - - // crate and destroy - pub fn LLVMPassManagerBuilderCreate() -> &'static mut PassManagerBuilder; - pub fn LLVMPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder); - - fn LLVMPassManagerBuilderSetOptLevel(PMB: &PassManagerBuilder, OptLevel: c_uint); - pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: &PassManagerBuilder, SizeLevel: c_uint); - fn LLVMPassManagerBuilderSLPVectorize(PMB: &PassManagerBuilder); - - pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderUseInlinerWithThreshold( - PMB: &PassManagerBuilder, - threshold: c_uint, - ); - pub fn LLVMPassManagerBuilderPopulateFunctionPassManager( - PMB: &PassManagerBuilder, - PM: &PassManager<'_>, - ); - pub fn LLVMPassManagerBuilderPopulateModulePassManager( - PMB: &PassManagerBuilder, - PM: &PassManager<'_>, - ); - pub fn LLVMPassManagerBuilderPopulateLTOPassManager( - PMB: &mut PassManagerBuilder, - PM: &PassManager<'_>, - Internalize: Bool, - RunInliner: Bool, - ); -} - -/// # Safety -/// This should always be save but this low level wrapper purposefully refrains from making Safety -/// garantuees -pub unsafe fn pass_manager_builder_set_opt_lvl(pmb: &PassManagerBuilder, opt_lvl: OptLevel) { - LLVMPassManagerBuilderSetOptLevel(pmb, opt_lvl as c_uint); - if opt_lvl > OptLevel::Less { - LLVMPassManagerBuilderSLPVectorize(pmb); - } -} - -// Core->Pass managers -extern "C" { - /// Creates a pass manager. - pub fn LLVMCreatePassManager() -> &'static mut PassManager<'static>; - - /// Creates a function-by-function pass manager - pub fn LLVMCreateFunctionPassManagerForModule<'a>(M: &'a Module) -> &'a mut PassManager<'a>; - - /// Disposes a pass manager. - pub fn LLVMDisposePassManager<'a>(PM: &'a mut PassManager<'a>); - - /// Runs a pass manager on a module. - pub fn LLVMRunPassManager(PM: &PassManager<'static>, M: &Module) -> Bool; - - fn LLVMInitializeFunctionPassManager(FPM: &PassManager<'_>) -> Bool; - fn LLVMRunFunctionPassManager<'a>(FPM: &PassManager<'a>, F: &'a Value) -> Bool; - fn LLVMFinalizeFunctionPassManager(FPM: &PassManager<'_>) -> Bool; -} - -/// # Safety -/// This function calls the LLVM C Api. -/// If the module or its contents have been incorrectly constructed this can cause UB -/// If the pass manager is not a function pass manager but a global pass manager this will cause UB -pub unsafe fn run_function_pass_manager<'a>(fpm: &PassManager<'a>, module: &'a Module) { - LLVMInitializeFunctionPassManager(fpm); - for fun in function_iter(module) { - LLVMRunFunctionPassManager(fpm, fun); - } - LLVMFinalizeFunctionPassManager(fpm); -} diff --git a/openvaf/llvm/src/support.rs b/openvaf/llvm/src/support.rs deleted file mode 100644 index b4cc4ec..0000000 --- a/openvaf/llvm/src/support.rs +++ /dev/null @@ -1,88 +0,0 @@ -use core::fmt; -use std::error::Error; -use std::ffi::{CStr, CString}; -use std::fmt::{Debug, Display, Formatter}; -use std::ops::Deref; - -use libc::c_char; - -use crate::{LLVMCreateMessage, LLVMDisposeMessage}; - -/// An owned LLVM String. Also known as a LLVM Message -#[derive(Eq)] -#[repr(transparent)] -pub struct LLVMString { - pub(crate) ptr: *const c_char, -} - -impl LLVMString { - /// # Safety - /// This functions requires a string that was allocated by LLVM! - pub unsafe fn new(ptr: *const c_char) -> Self { - LLVMString { ptr } - } - - // /// This is a convenience method for creating a Rust `String`, - // /// however; it *will* reallocate. `LLVMString` should be used - // /// as much as possible to save memory since it is allocated by - // /// LLVM. It's essentially a `CString` with a custom LLVM - // /// deallocator - // pub fn to_string(&self) -> String { - // (*self).to_string_lossy().into_owned() - // } - - // /// This method will allocate a c string through LLVM - pub(crate) fn create_from_str(string: &str) -> LLVMString { - let msg = CString::new(string).unwrap(); - unsafe { LLVMString::new(LLVMCreateMessage(msg.as_ptr() as *const _)) } - } - - /// This method will allocate a c string through LLVM - pub fn create_from_c_str(string: &CStr) -> LLVMString { - unsafe { LLVMString::new(LLVMCreateMessage(string.as_ptr() as *const _)) } - } -} - -impl Deref for LLVMString { - type Target = CStr; - - fn deref(&self) -> &Self::Target { - unsafe { CStr::from_ptr(self.ptr) } - } -} - -impl Debug for LLVMString { - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "{:?}", self.deref()) - } -} - -impl Display for LLVMString { - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", self.deref().to_string_lossy()) - } -} - -impl PartialEq for LLVMString { - fn eq(&self, other: &LLVMString) -> bool { - **self == **other - } -} - -impl Error for LLVMString { - fn description(&self) -> &str { - self.to_str().expect("Could not convert LLVMString to str (likely invalid unicode)") - } - - fn cause(&self) -> Option<&dyn Error> { - None - } -} - -impl Drop for LLVMString { - fn drop(&mut self) { - unsafe { - LLVMDisposeMessage(self.ptr as *mut _); - } - } -} diff --git a/openvaf/llvm/src/targets.rs b/openvaf/llvm/src/targets.rs deleted file mode 100644 index 8fca941..0000000 --- a/openvaf/llvm/src/targets.rs +++ /dev/null @@ -1,113 +0,0 @@ -use std::ffi::{CStr, CString}; -use std::mem::MaybeUninit; - -use ::libc::c_char; -use libc::{c_uint, c_ulonglong}; - -use crate::support::LLVMString; -use crate::{ - Bool, CodeGenFileType, CodeModel, Module, OptLevel, RelocMode, Target, TargetData, - TargetMachine, Type, -}; - -extern "C" { - fn LLVMGetTargetFromTriple( - Triple: *const c_char, - T: &mut Option<&'static Target>, - ErrorMessage: *mut *mut c_char, - ) -> Bool; - fn LLVMCreateTargetMachine( - T: &Target, - Triple: *const c_char, - CPU: *const c_char, - Features: *const c_char, - Level: OptLevel, - Reloc: RelocMode, - CodeModel: CodeModel, - ) -> Option<&'static mut TargetMachine>; - pub fn LLVMDisposeTargetMachine(target_machine: &'static mut TargetMachine); - /// Create a DataLayout based on the target machine. - pub fn LLVMTargetMachineEmitToFile( - target: &TargetMachine, - module: &Module, - file_name: *const c_char, - codegen: CodeGenFileType, - ErrorMessage: *mut *mut c_char, - ) -> Bool; - // pub fn LLVMTargetMachineEmitToMemoryBuffer( - // T: LLVMTargetMachineRef, - // M: LLVMModuleRef, - // codegen: LLVMCodeGenFileType, - // ErrorMessage: *mut *mut ::libc::c_char, - // OutMemBuf: *mut LLVMMemoryBufferRef, - // ) -> LLVMBool; - pub fn LLVMGetHostCPUName() -> *const c_char; - pub fn LLVMGetHostCPUFeatures() -> *const c_char; - - /// Normalize a target triple. The result needs to be disposed with LLVMDisposeMessage. - fn LLVMNormalizeTargetTriple(triple: *const c_char) -> *mut c_char; - fn LLVMSetTarget(module: &Module, triple: *const c_char); - - pub fn LLVMOffsetOfElement(TD: &TargetData, struct_ty: &Type, elem: c_uint) -> c_ulonglong; - - pub fn LLVMCreateTargetData(StringRep: *const c_char) -> &'static mut TargetData; - pub fn LLVMDisposeTargetData(target_data: &'static mut TargetData); - - pub fn LLVMABISizeOfType(data: &TargetData, ty: &Type) -> c_ulonglong; - pub fn LLVMABIAlignmentOfType(data: &TargetData, ty: &Type) -> c_uint; -} - -/// # Safety -/// -/// This function calls the LLVM C interface and may emit unsafety for invalid inputs. -/// Specifically this function is not thread save! -pub unsafe fn create_target( - triple: &str, - cpu: &str, - features: &str, - level: OptLevel, - reloc_mode: RelocMode, - code_model: CodeModel, -) -> Result<&'static mut TargetMachine, LLVMString> { - let triple_ = LLVMString::create_from_c_str(&CString::new(triple).unwrap()); - let triple_ = LLVMString::new(LLVMNormalizeTargetTriple(triple_.as_ptr())); - let mut target = None; - let mut err_string = MaybeUninit::uninit(); - - let code = LLVMGetTargetFromTriple(triple_.as_ptr(), &mut target, err_string.as_mut_ptr()); - - if code == 1 { - return Err(LLVMString::new(err_string.assume_init())); - } - - let cpu = LLVMString::create_from_str(cpu); - let features = CString::new(features).unwrap(); - let target = target.unwrap(); - - let target_machine = LLVMCreateTargetMachine( - target, - triple_.as_ptr(), - cpu.as_ptr(), - features.as_ptr(), - level, - reloc_mode, - code_model, - ); - - target_machine.ok_or_else(|| { - LLVMString::create_from_c_str( - CStr::from_bytes_with_nul( - format!("error: code gen not available for target \"{}\"\0", triple).as_bytes(), - ) - .unwrap(), - ) - }) -} - -/// # Safety -/// This function calls LLVM raw ffi which is implemented in C and may be unsound -pub unsafe fn set_normalized_target(module: &Module, triple: &str) { - let triple = LLVMString::create_from_c_str(&CString::new(triple).unwrap()); - let triple = LLVMString::new(LLVMNormalizeTargetTriple(triple.as_ptr())); - LLVMSetTarget(module, triple.as_ptr()) -} diff --git a/openvaf/llvm/src/types.rs b/openvaf/llvm/src/types.rs deleted file mode 100644 index f6a60d1..0000000 --- a/openvaf/llvm/src/types.rs +++ /dev/null @@ -1,127 +0,0 @@ -use std::mem::forget; - -use ::libc::{c_char, c_uint}; - -use crate::{Bool, Context, Type, TypeKind}; - -extern "C" { - pub fn LLVMGetTypeKind(ty: &Type) -> TypeKind; - // pub fn LLVMTypeIsSized(Ty: &'a Type) -> LLVMBool; - // pub fn LLVMGetTypeContext(Ty: &'a Type) -> ContextRef; - // pub fn LLVMDumpType(Val: &'a Type); - pub fn LLVMPrintTypeToString(Val: &Type) -> *mut c_char; - - // Core->Types->Integer - pub fn LLVMInt1TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - pub fn LLVMInt8TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMInt16TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - pub fn LLVMInt32TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - pub fn LLVMInt64TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMInt128TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - pub fn LLVMIntTypeInContext<'a>(ctx: &'a Context, num_bits: c_uint) -> &'a Type; - // pub fn LLVMGetIntTypeWidth<'a>(ty: &Type) -> c_uint; - - // Core->Types->Floating-Point - // pub fn LLVMHalfTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMBFloatTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMFloatTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - pub fn LLVMDoubleTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMX86FP80TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMFP128TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMPPCFP128TypeInContext<'a>(ctx: &'a Context) -> &'a Type; - - // Core->Types->Function - pub fn LLVMFunctionType<'a>( - ReturnType: &'a Type, - ParamTypes: *const &'a Type, - ParamCount: c_uint, - IsVarArg: Bool, - ) -> &'a Type; - pub fn LLVMIsFunctionVarArg<'a>(fun_ty: &'a Type) -> Bool; - pub fn LLVMGetReturnType<'a>(fun_ty: &'a Type) -> &'a Type; - pub fn LLVMCountParamTypes<'a>(fun_ty: &'a Type) -> c_uint; - pub fn LLVMGetParamTypes<'a>(fun_ty: &'a Type, dst: *mut &'a Type); - - // Core->Types->Struct - pub fn LLVMStructTypeInContext<'a>( - ctx: &'a Context, - ElementTypes: *const &'a Type, - ElementCount: c_uint, - Packed: Bool, - ) -> &'a Type; - pub fn LLVMStructCreateNamed<'a>(ctx: &'a Context, Name: *const c_char) -> &'a Type; - pub fn LLVMGetStructName<'a>(ty: &'a Type) -> *const c_char; - pub fn LLVMStructSetBody<'a>( - struct_ty: &'a Type, - ElementTypes: *const &'a Type, - ElementCount: c_uint, - Packed: Bool, - ); - pub fn LLVMCountStructElementTypes(struct_ty: &Type) -> c_uint; - fn LLVMGetStructElementTypes<'a>(struct_ty: &'a Type, dst: *mut &'a Type); - ///// Get the type of the element at the given index in a structure. - ///// - ///// Added in LLVM 3.7. - pub fn LLVMStructGetTypeAtIndex<'a>(struct_ty: &'a Type, i: c_uint) -> &'a Type; - ///// Determine whether a structure is packed. - //pub fn LLVMIsPackedStruct(struct_ty: &Type) -> Bool; - //pub fn LLVMIsOpaqueStruct(struct_ty: &Type) -> Bool; - //pub fn LLVMIsLiteralStruct(struct_ty: &Type) -> Bool; - - //// Core->Types->Sequential - // pub fn LLVMGetElementType<'a>(ty: &'a Type) -> &'a Type; - ///// Get the subtypes of the given type. - //pub fn LLVMGetSubtypes<'a>(ty: &'a Type, arr: *mut &'a Type); - ///// Return the number of types in the derived type. - //pub fn LLVMGetNumContainedTypes<'a>(ty: &'a Type) -> c_uint; - pub fn LLVMArrayType<'a>(elem: &'a Type, elem_cnt: c_uint) -> &'a Type; - // pub fn LLVMGetArrayLength(ArrayTy: &'a Type) -> c_uint; - pub fn LLVMPointerType<'a>(elem: &'a Type, address_space: AddressSpace) -> &'a Type; - // pub fn LLVMGetPointerAddressSpace(PointerTy: &'a Type) -> c_uint; - // pub fn LLVMVectorType(ElementType: &'a Type, ElementCount: c_uint) -> &'a Type; - /// Create a vector type that contains a defined type and has a scalable - /// number of elements. - /// - /// The created type will exist in the context that its element type - /// exists in. - // pub fn LLVMScalableVectorType(ElementType: &'a Type, ElementCount: c_uint) -> &'a Type; - /// Obtain the (possibly scalable) number of elements in a vector type. - // pub fn LLVMGetVectorSize(VectorTy: &'a Type) -> c_uint; - - // Core->Types->Other - pub fn LLVMVoidTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMLabelTypeInContext<'a>(ctx: &'a Context) -> &'a Type; - // pub fn LLVMX86MMXTypeInContext(ctx: &'a Context) -> &'a Type; - // pub fn LLVMX86AMXTypeInContext(ctx: &'a Context) -> &'a Type; - // pub fn LLVMTokenTypeInContext(ctx: &'a Context) -> &'a Type; - // pub fn LLVMMetadataTypeInContext(ctx: &'a Context) -> &'a Type; - // pub fn LLVMVoidType() -> &'a Type; - // pub fn LLVMLabelType() -> &'a Type; - // pub fn LLVMX86MMXType() -> &'a Type; - // pub fn LLVMX86AMXType() -> &'a Type; -} - -/// An identifier that specifies the address space that some operation -/// should operate on. Special address spaces have an effect on code generation, -/// depending on the target and the address spaces it implements. -#[repr(transparent)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct AddressSpace(pub c_uint); - -impl AddressSpace { - /// The default address space, corresponding to data space. - pub const DATA: Self = AddressSpace(0); -} - -/// # Safety -/// struct_ty must be a valid struct type -pub unsafe fn struct_element_types(struct_ty: &Type) -> Box<[&Type]> { - let count = LLVMCountStructElementTypes(struct_ty); - - let mut raw_vec: Vec<&Type> = Vec::with_capacity(count as usize); - let ptr = raw_vec.as_mut_ptr(); - forget(raw_vec); - - LLVMGetStructElementTypes(struct_ty, ptr); - Vec::from_raw_parts(ptr, count as usize, count as usize).into_boxed_slice() -} diff --git a/openvaf/llvm/src/util.rs b/openvaf/llvm/src/util.rs deleted file mode 100644 index f9b1412..0000000 --- a/openvaf/llvm/src/util.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::marker::PhantomData; - -enum Opaque {} - -#[repr(C)] -pub(crate) struct InvariantOpaque<'a> { - _marker: PhantomData<&'a mut &'a ()>, - _opaque: Opaque, -} diff --git a/openvaf/llvm/src/values.rs b/openvaf/llvm/src/values.rs deleted file mode 100644 index 702b17f..0000000 --- a/openvaf/llvm/src/values.rs +++ /dev/null @@ -1,434 +0,0 @@ -use libc::{c_char, c_double, c_uint, c_ulonglong}; - -use crate::{ - BasicBlock, Bool, CallConv, Context, DLLStorageClass, Linkage, Module, Type, UnnamedAddr, - Value, Visibility, -}; - -// Core->Values -extern "C" { - // Core->Values->General - // Get the enumerated kind of a Value instance. - pub fn LLVMTypeOf(val: &Value) -> &Type; - - // pub fn LLVMGetValueName2(val: &'a Value, Length: *mut ::libc::size_t) -> *const ::libc::c_char; - // pub fn LLVMSetValueName2(val: &'a Value, Name: *const ::libc::c_char, NameLen: ::libc::size_t); - - // pub fn LLVMDumpValue(Val: &'a Value); - pub fn LLVMPrintValueToString(val: &Value) -> *mut c_char; - pub fn LLVMReplaceAllUsesWith<'a>(old_val: &'a Value, new_val: &'a Value); - /// Determine whether the specified value instance is constant. - // pub fn LLVMIsConstant(Val: &'a Value) -> LLVMBool; - // pub fn LLVMIsUndef(Val: &'a Value) -> LLVMBool; - // /// Determine whether a value instance is poisonous. - // pub fn LLVMIsPoison(Val: &'a Value) -> LLVMBool; - // pub fn LLVMIsAMDNode(Val: &'a Value) -> &'a Value; - // pub fn LLVMIsAMDString(Val: &'a Value) -> &'a Value; - - // Core->Values->Usage - // pub fn LLVMGetFirstUse(Val: &'a Value) -> LLVMUseRef; - // pub fn LLVMGetNextUse(U: LLVMUseRef) -> LLVMUseRef; - // pub fn LLVMGetUser(U: LLVMUseRef) -> &'a Value; - // pub fn LLVMGetUsedValue(U: LLVMUseRef) -> &'a Value; - - // Core->Values->User value - // pub fn LLVMGetOperand(Val: &'a Value, Index: ::libc::c_uint) -> &'a Value; - // pub fn LLVMGetOperandUse(Val: &'a Value, Index: ::libc::c_uint) -> LLVMUseRef; - // pub fn LLVMSetOperand(User: &'a Value, Index: ::libc::c_uint, Val: &'a Value); - // pub fn LLVMGetNumOperands(Val: &'a Value) -> ::libc::c_int; - - // Core->Values->Constants - pub fn LLVMConstNull(ty: &Type) -> &Value; - pub fn LLVMConstAllOnes(ty: &Type) -> &Value; - pub fn LLVMGetUndef(ty: &Type) -> &Value; - /// Obtain a constant value referring to a poison value of a type. - // pub fn LLVMGetPoison(Ty: TypeRef) -> &'a Value; - // pub fn LLVMIsNull(Val: &'a Value) -> LLVMBool; - pub fn LLVMConstPointerNull(ty: &Type) -> &Value; - - // Core->Values->Constants->Scalar - pub fn LLVMConstInt(ty: &Type, val: c_ulonglong, sign_extend: Bool) -> &Value; - // pub fn LLVMConstIntOfArbitraryPrecision( - // IntTy: TypeRef, - // NumWords: ::libc::c_uint, - // Words: *const u64, - // ) -> &'a Value; - // pub fn LLVMConstIntOfString( - // IntTy: TypeRef, - // Text: *const ::libc::c_char, - // Radix: u8, - // ) -> &'a Value; - // pub fn LLVMConstIntOfStringAndSize( - // IntTy: TypeRef, - // Text: *const ::libc::c_char, - // SLen: ::libc::c_uint, - // Radix: u8, - // ) -> &'a Value; - pub fn LLVMConstReal(RealTy: &Type, val: c_double) -> &Value; - // pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const ::libc::c_char) -> &'a Value; - // pub fn LLVMConstRealOfStringAndSize( - // RealTy: TypeRef, - // Text: *const ::libc::c_char, - // SLen: ::libc::c_uint, - // ) -> &'a Value; - // pub fn LLVMConstIntGetZExtValue(ConstantVal: &'a Value) -> ::libc::c_ulonglong; - // pub fn LLVMConstIntGetSExtValue(ConstantVal: &'a Value) -> ::libc::c_longlong; - // pub fn LLVMConstRealGetDouble( - // ConstantVal: &'a Value, - // losesInfo: *mut LLVMBool, - // ) -> ::libc::c_double; - - // Core->Values->Constants->Composite - pub fn LLVMConstStringInContext( - C: &Context, - Str: *const c_char, - Length: c_uint, - DontNullTerminate: Bool, - ) -> &Value; - // pub fn LLVMConstString( - // Str: *const ::libc::c_char, - // Length: ::libc::c_uint, - // DontNullTerminate: LLVMBool, - // ) -> &'a Value; - // pub fn LLVMIsConstantString(c: &'a Value) -> LLVMBool; - // pub fn LLVMGetAsString(C: &'a Value, Length: *mut ::libc::size_t) -> *const ::libc::c_char; - pub fn LLVMConstStructInContext<'a>( - C: &'a Context, - ConstantVals: *const &'a Value, - Count: c_uint, - Packed: Bool, - ) -> &'a Value; - pub fn LLVMConstArray<'a>( - element_ty: &'a Type, - vals: *const &'a Value, - len: c_uint, - ) -> &'a Value; - pub fn LLVMConstNamedStruct<'a>( - ty: &'a Type, - ConstantVals: *const &'a Value, - Count: c_uint, - ) -> &'a Value; - // pub fn LLVMGetElementAsConstant(C: &'a Value, idx: ::libc::c_uint) -> &'a Value; - // pub fn LLVMConstVector(ScalarConstantVals: *mut &'a Value, Size: ::libc::c_uint) -> &'a Value; - - // Core->Values->Constants->Constant expressions - // pub fn LLVMGetConstOpcode(ConstantVal: &'a Value) -> Opcode; - // pub fn LLVMAlignOf(Ty: TypeRef) -> &'a Value; - // pub fn LLVMSizeOf(Ty: TypeRef) -> &'a Value; - // pub fn LLVMConstNeg(ConstantVal: &'a Value) -> &'a Value; - // pub fn LLVMConstNSWNeg(ConstantVal: &'a Value) -> &'a Value; - // pub fn LLVMConstNUWNeg(ConstantVal: &'a Value) -> &'a Value; - // pub fn LLVMConstFNeg(ConstantVal: &'a Value) -> &'a Value; - // pub fn LLVMConstNot(ConstantVal: &'a Value) -> &'a Value; - // pub fn LLVMConstAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNSWAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNUWAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstFAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNSWSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNUWSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstFSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNSWMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstNUWMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstFMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstUDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstExactUDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstSDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstExactSDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstFDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstURem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstSRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstFRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstAnd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstOr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstXor(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstICmp( - // Predicate: LLVMIntPredicate, - // LHSConstant: &'a Value, - // RHSConstant: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstFCmp( - // Predicate: LLVMRealPredicate, - // LHSConstant: &'a Value, - // RHSConstant: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstShl(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstLShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - // pub fn LLVMConstAShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstInBoundsGEP2<'a>( - elem_ty: &'a Type, - ConstantVal: &'a Value, - ConstantIndices: *const &'a Value, - NumIndices: c_uint, - ) -> &'a Value; - // pub fn LLVMConstGEP2<'a>( - // ty: &'a Type, - // ConstantVal: &'a Value, - // ConstantIndices: *const &'a Value, - // NumIndices: c_uint, - // ) -> &'a Value; - // pub fn LLVMConstInBoundsGEP( - // ConstantVal: &'a Value, - // ConstantIndices: *mut &'a Value, - // NumIndices: ::libc::c_uint, - // ) -> &'a Value; - // pub fn LLVMConstInBoundsGEP2<'a>( - // ty: &'a Type, - // ConstantVal: &'a Value, - // ConstantIndices: *const &'a Value, - // NumIndices: c_uint, - // ) -> &'a Value; - // pub fn LLVMConstTrunc(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstSExt(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstZExt(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstFPTrunc(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstFPExt(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstUIToFP(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstSIToFP(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstFPToUI(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstFPToSI(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstPtrToInt(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstIntToPtr(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstBitCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstAddrSpaceCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstZExtOrBitCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstSExtOrBitCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstTruncOrBitCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstPointerCast<'a>(const_val: &'a Value, ty: &'a Type) -> &'a Value; - // pub fn LLVMConstIntCast<'a>( - // ConstantVal: &'a Value, - // ToType: &'a Type, - // isSigned: Bool, - // ) -> &'a Value; - // pub fn LLVMConstFPCast(ConstantVal: &'a Value, ToType: TypeRef) -> &'a Value; - // pub fn LLVMConstSelect( - // ConstantCondition: &'a Value, - // ConstantIfTrue: &'a Value, - // ConstantIfFalse: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstExtractElement( - // VectorConstant: &'a Value, - // IndexConstant: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstInsertElement( - // VectorConstant: &'a Value, - // ElementValueConstant: &'a Value, - // IndexConstant: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstShuffleVector( - // VectorAConstant: &'a Value, - // VectorBConstant: &'a Value, - // MaskConstant: &'a Value, - // ) -> &'a Value; - // pub fn LLVMConstExtractValue( - // AggConstant: &'a Value, - // IdxList: *mut ::libc::c_uint, - // NumIdx: ::libc::c_uint, - // ) -> &'a Value; - // pub fn LLVMConstInsertValue( - // AggConstant: &'a Value, - // ElementValueConstant: &'a Value, - // IdxList: *mut ::libc::c_uint, - // NumIdx: ::libc::c_uint, - // ) -> &'a Value; - // pub fn LLVMBlockAddress(F: &'a Value, BB: LLVMBasicBlockRef) -> &'a Value; - - // Core->Values->Constants->Global Values - // pub fn LLVMGetGlobalParent(global: &'a Value) -> ModuleRef; - pub fn LLVMIsDeclaration(global: &Value) -> Bool; - // pub fn LLVMGetLinkage(global: &Value) -> Linkage; - pub fn LLVMSetLinkage(global: &Value, Linkage: Linkage); - // pub fn LLVMGetSection(global: &'a Value) -> *const ::libc::c_char; - // pub fn LLVMSetSection(global: &'a Value, Section: *const ::libc::c_char); - // pub fn LLVMGetVisibility(global: &'a Value) -> Visibility; - pub fn LLVMSetVisibility(global: &Value, viz: Visibility); - // pub fn LLVMGetDLLStorageClass(global: &'a Value) -> LLVMDLLStorageClass; - pub fn LLVMSetDLLStorageClass(global: &Value, Class: DLLStorageClass); - - // pub fn LLVMGetUnnamedAddress(global: &'a Value) -> LLVMUnnamedAddr; - pub fn LLVMSetUnnamedAddress(global: &Value, UnnamedAddr: UnnamedAddr); - // pub fn LLVMGlobalGetValueType(global: &'a Value) -> TypeRef; - - // pub fn LLVMGetAlignment(V: &'a Value) -> ::libc::c_uint; - pub fn LLVMSetAlignment(val: &Value, align: c_uint); - - // pub fn LLVMGlobalSetMetadata(global: &'a Value, Kind: ::libc::c_uint, MD: &'a Metadata); - // pub fn LLVMGlobalEraseMetadata(global: &'a Value, Kind: ::libc::c_uint); - // pub fn LLVMGlobalClearMetadata(global: &'a Value); - // pub fn LLVMGlobalCopyAllMetadata( - // Value: &'a Value, - // NumEntries: *mut ::libc::size_t, - // ) -> *mut LLVMValueMetadataEntry; - // pub fn LLVMDisposeValueMetadataEntries(Entries: *mut LLVMValueMetadataEntry); - // pub fn LLVMValueMetadataEntriesGetKind( - // Entries: *mut LLVMValueMetadataEntry, - // Index: ::libc::c_uint, - // ) -> ::libc::c_uint; - // pub fn LLVMValueMetadataEntriesGetMetadata( - // Entries: *mut LLVMValueMetadataEntry, - // Index: ::libc::c_uint, - // ) -> &'a Metadata; - - // // Core->Values->Constants->Global Variables - pub fn LLVMAddGlobal<'a>(module: &'a Module, ty: &'a Type, name: *const c_char) -> &'a Value; - // pub fn LLVMAddGlobalInAddressSpace( - // M: ModuleRef, - // Ty: TypeRef, - // Name: *const ::libc::c_char, - // AddressSpace: ::libc::c_uint, - // ) -> &'a Value; - pub fn LLVMGetNamedGlobal(module: &Module, name: *const c_char) -> Option<&Value>; - // pub fn LLVMGetFirstGlobal(M: ModuleRef) -> &'a Value; - // pub fn LLVMGetLastGlobal(M: ModuleRef) -> &'a Value; - // pub fn LLVMGetNextGlobal(GlobalVar: &'a Value) -> &'a Value; - // pub fn LLVMGetPreviousGlobal(GlobalVar: &'a Value) -> &'a Value; - // pub fn LLVMDeleteGlobal(GlobalVar: &'a Value); - // pub fn LLVMGetInitializer(GlobalVar: &'a Value) -> &'a Value; - pub fn LLVMSetInitializer<'a>(global: &'a Value, const_val: &'a Value); - // pub fn LLVMIsThreadLocal(GlobalVar: &'a Value) -> LLVMBool; - // pub fn LLVMSetThreadLocal(GlobalVar: &'a Value, IsThreadLocal: LLVMBool); - // pub fn LLVMIsGlobalConstant(GlobalVar: &'a Value) -> LLVMBool; - pub fn LLVMSetGlobalConstant<'a>(GlobalVar: &'a Value, IsConstant: Bool); - // pub fn LLVMGetThreadLocalMode(GlobalVar: &'a Value) -> LLVMThreadLocalMode; - // pub fn LLVMSetThreadLocalMode(GlobalVar: &'a Value, Mode: LLVMThreadLocalMode); - // pub fn LLVMIsExternallyInitialized(GlobalVar: &'a Value) -> LLVMBool; - // pub fn LLVMSetExternallyInitialized(GlobalVar: &'a Value, IsExtInit: LLVMBool); - - //// Core->Values->Constants->Global Aliases - // /// Obtain a GlobalAlias value from a Module by its name. - // /// - // /// The returned value corresponds to a llvm::GlobalAlias value. - //pub fn LLVMGetNamedGlobalAlias( - // M: ModuleRef, - // Name: *const ::libc::c_char, - // NameLen: ::libc::size_t, - //) -> &'a Value; - ///// Obtain an iterator to the first GlobalAlias in a Module. - //pub fn LLVMGetFirstGlobalAlias(M: ModuleRef) -> &'a Value; - ///// Obtain an iterator to the last GlobalAlias in a Module. - //pub fn LLVMGetLastGlobalAlias(M: ModuleRef) -> &'a Value; - ///// Advance a GlobalAlias iterator to the next GlobalAlias. - ///// - ///// Returns NULL if the iterator was already at the end and there are no more global aliases. - //pub fn LLVMGetNextGlobalAlias(GA: &'a Value) -> &'a Value; - ///// Decrement a GlobalAlias iterator to the previous GlobalAlias. - ///// - ///// Returns NULL if the iterator was already at the beginning and there are no previous global aliases. - //pub fn LLVMGetPreviousGlobalAlias(GA: &'a Value) -> &'a Value; - ///// Retrieve the target value of an alias. - //pub fn LLVMAliasGetAliasee(Alias: &'a Value) -> &'a Value; - ///// Set the target value of an alias. - //pub fn LLVMAliasSetAliasee(Alias: &'a Value, Aliasee: &'a Value); - - //pub fn LLVMAddAlias( - // M: ModuleRef, - // Ty: TypeRef, - // Aliasee: &'a Value, - // Name: *const ::libc::c_char, - //) -> &'a Value; - - //..->Function Values - //// pub fn LLVMDeleteFunction(Fn: &'a Value); - ///// Check whether the given function has a personality function. - //// pub fn LLVMHasPersonalityFn(Fn: &'a Value) -> LLVMBool; - ///// Obtain the personality function attached to the function. - ///// - ///// Added in LLVM 3.7. - //pub fn LLVMGetPersonalityFn(Fn: &'a Value) -> &'a Value; - ///// Set the personality function attached to the function. - ///// - ///// Added in LLVM 3.7. - //pub fn LLVMSetPersonalityFn(Fn: &'a Value, PersonalityFn: &'a Value); - ///// Obtain the intrinsic ID number which matches the given function name. - //pub fn LLVMLookupIntrinsicID( - // Name: *const ::libc::c_char, - // NameLen: ::libc::size_t, - //) -> ::libc::c_uint; - ///// Obtain the ID number from a function instance. - //pub fn LLVMGetIntrinsicID(Fn: &'a Value) -> ::libc::c_uint; - //pub fn LLVMGetIntrinsicDeclaration( - // Mod: ModuleRef, - // ID: ::libc::c_uint, - // ParamTypes: *mut TypeRef, - // ParamCount: ::libc::size_t, - //) -> &'a Value; - //pub fn LLVMIntrinsicGetType( - // Ctx: ContextRef, - // ParamTypes: *mut TypeRef, - // ParamCount: ::libc::size_t, - //) -> TypeRef; - //pub fn LLVMIntrinsicGetName( - // ID: ::libc::c_uint, - // NameLength: *mut ::libc::size_t, - //) -> *const ::libc::c_char; - //pub fn LLVMIntrinsicCopyOverloadedName2( - // Mod: ModuleRef, - // ID: ::libc::c_uint, - // ParamTypes: *mut TypeRef, - // ParamCount: ::libc::size_t, - // NameLength: *mut ::libc::size_t, - //) -> *const ::libc::c_char; - //pub fn LLVMIntrinsicIsOverloaded(ID: ::libc::c_uint) -> LLVMBool; - pub fn LLVMGetFunctionCallConv(Fn: &Value) -> CallConv; - pub fn LLVMSetFunctionCallConv(fun: &Value, cc: CallConv); - pub fn LLVMSetInstructionCallConv(instr: &Value, cc: CallConv); - //pub fn LLVMGetGC(Fn: &'a Value) -> *const ::libc::c_char; - //pub fn LLVMSetGC(Fn: &'a Value, Name: *const ::libc::c_char); - //pub fn LLVMAddAttributeAtIndex(F: &'a Value, Idx: LLVMAttributeIndex, A: LLVMAttributeRef); - //pub fn LLVMGetAttributeCountAtIndex(F: &'a Value, Idx: LLVMAttributeIndex) -> ::libc::c_uint; - //pub fn LLVMGetAttributesAtIndex( - // F: &'a Value, - // Idx: LLVMAttributeIndex, - // Attrs: *mut LLVMAttributeRef, - //); - //pub fn LLVMGetEnumAttributeAtIndex( - // F: &'a Value, - // Idx: LLVMAttributeIndex, - // KindID: ::libc::c_uint, - //) -> LLVMAttributeRef; - //pub fn LLVMGetStringAttributeAtIndex( - // F: &'a Value, - // Idx: LLVMAttributeIndex, - // K: *const ::libc::c_char, - // KLen: ::libc::c_uint, - //) -> LLVMAttributeRef; - //pub fn LLVMRemoveEnumAttributeAtIndex( - // F: &'a Value, - // Idx: LLVMAttributeIndex, - // KindID: ::libc::c_uint, - //); - //pub fn LLVMRemoveStringAttributeAtIndex( - // F: &'a Value, - // Idx: LLVMAttributeIndex, - // K: *const ::libc::c_char, - // KLen: ::libc::c_uint, - //); - //pub fn LLVMAddTargetDependentFunctionAttr( - // Fn: &'a Value, - // A: *const ::libc::c_char, - // V: *const ::libc::c_char, - //); - - // ..->Function Values->Function Parameters - // pub fn LLVMCountParams(Fn: &'a Value) -> ::libc::c_uint; - // pub fn LLVMGetParams(Fn: &'a Value, Params: *mut &'a Value); - pub fn LLVMGetParam(fun: &Value, index: c_uint) -> &Value; - - // pub fn LLVMGetParamParent(Inst: &'a Value) -> &'a Value; - // pub fn LLVMGetFirstParam(Fn: &'a Value) -> &'a Value; - // pub fn LLVMGetLastParam(Fn: &'a Value) -> &'a Value; - // pub fn LLVMGetNextParam(Arg: &'a Value) -> &'a Value; - // pub fn LLVMGetPreviousParam(Arg: &'a Value) -> &'a Value; - // pub fn LLVMSetParamAlignment(Arg: &'a Value, Align: ::libc::c_uint); - pub fn LLVMSetPartialFastMath(val: &Value); - pub fn LLVMSetFastMath(val: &Value); - - // Instruction->PHI Nodes - pub fn LLVMAddIncoming<'a>( - PhiNode: &'a Value, - IncomingValues: *const &'a Value, - IncomingBlocks: *const &'a BasicBlock, - Count: c_uint, - ); -} diff --git a/openvaf/llvm/wrapper/OpenVafWrapper.cpp b/openvaf/llvm/wrapper/OpenVafWrapper.cpp deleted file mode 100644 index ce0592b..0000000 --- a/openvaf/llvm/wrapper/OpenVafWrapper.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "llvm/IR/Instructions.h" -#include "llvm/Support/CrashRecoveryContext.h" -#include -#include -#include - -#include -#include -#include - -using namespace llvm; - -extern "C" { - -// Enable some fast-math flags for an operation -// These flags are used for derivatives by default because they only change -// the rounding behaviour which is not relevant for automatically generated code -// (derivatives in OpenVAF) -// -// https://llvm.org/docs/LangRef.html#fast-math-flags -void LLVMSetPartialFastMath(LLVMValueRef V) { - if (auto I = dyn_cast(unwrap(V))) { - I->setHasAllowReassoc(true); - I->setHasAllowReciprocal(true); - I->setHasAllowContract(true); - } -} - -// Enable fast-math flags for an operation -// https://llvm.org/docs/LangRef.html#fast-math-flags -void LLVMSetFastMath(LLVMValueRef V) { - if (auto I = dyn_cast(unwrap(V))) { - I->setFast(true); - } -} - -void LLVMPurgeAttrs(LLVMValueRef V) { - if (auto func = dyn_cast(unwrap(V))) { - func->setAttributes(AttributeList()); - } -} - -void LLVMPassManagerBuilderSLPVectorize(LLVMPassManagerBuilderRef PMB) { - PassManagerBuilder *Builder = unwrap(PMB); - Builder->SLPVectorize = true; -} -} diff --git a/openvaf/mir_llvm/Cargo.toml b/openvaf/mir_llvm/Cargo.toml index 5d47d54..00ffe9d 100644 --- a/openvaf/mir_llvm/Cargo.toml +++ b/openvaf/mir_llvm/Cargo.toml @@ -10,7 +10,10 @@ doctest = false [dependencies] -llvm = { version = "0.0.0", path = "../llvm" } + +llvm-sys = {version="181.1.1", features=["prefer-dynamic"]} +#llvm = { version = "0.0.0", path = "../llvm" } +target-lexicon = "0.12" mir = { version = "0.0.0", path = "../mir" } target = { version = "0.0.0", path = "../target" } base_n = {version = "1", path="../../lib/base_n"} @@ -21,3 +24,4 @@ ahash = "0.8" lasso = { version = "0.7", features = ["ahash"] } libc = "0.2" log = "0.4.19" + From dfdacb6cffa70201e5ddf19955f857e33b2e76d1 Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Wed, 30 Oct 2024 16:44:35 +0100 Subject: [PATCH 3/9] Adding LLVM18 In one single commit to audit the differences better --- .gitignore | 3 + Cargo.lock | 88 +- openvaf/hir/Cargo.toml | 2 +- openvaf/mir_llvm/src/builder.rs | 826 ++++++++++++------- openvaf/mir_llvm/src/callbacks.rs | 71 +- openvaf/mir_llvm/src/context.rs | 67 +- openvaf/mir_llvm/src/declarations.rs | 161 ++-- openvaf/mir_llvm/src/intrinsics.rs | 8 +- openvaf/mir_llvm/src/lib.rs | 380 +++++++-- openvaf/mir_llvm/src/types.rs | 191 +++-- openvaf/openvaf-driver/Cargo.toml | 1 + openvaf/openvaf-driver/src/cli_process.rs | 12 +- openvaf/openvaf-driver/src/crash_report.rs | 6 +- openvaf/openvaf/Cargo.toml | 3 +- openvaf/openvaf/src/lib.rs | 4 +- openvaf/openvaf/tests/integration.rs | 4 +- openvaf/osdi/Cargo.toml | 5 +- openvaf/osdi/src/access.rs | 272 ++++-- openvaf/osdi/src/bitfield.rs | 140 +++- openvaf/osdi/src/compilation_unit.rs | 321 +++++-- openvaf/osdi/src/eval.rs | 232 ++++-- openvaf/osdi/src/inst_data.rs | 668 ++++++++++----- openvaf/osdi/src/lib.rs | 72 +- openvaf/osdi/src/load.rs | 323 +++++--- openvaf/osdi/src/metadata.rs | 56 +- openvaf/osdi/src/metadata/osdi_0_4.rs | 158 ++-- openvaf/osdi/src/model_data.rs | 162 ++-- openvaf/osdi/src/setup.rs | 149 ++-- openvaf/osdi/src/tests.rs | 4 +- openvaf/osdi/tests/data_tests.rs | 12 +- openvaf/preprocessor/src/scoped_arc_arena.rs | 2 +- openvaf/sim_back/Cargo.toml | 2 +- openvaf/syntax/Cargo.toml | 2 +- sourcegen/src/osdi.rs | 16 +- verilogae/verilogae/Cargo.toml | 5 +- verilogae/verilogae/src/api.rs | 4 +- verilogae/verilogae/src/back.rs | 184 +++-- verilogae/verilogae/src/lib.rs | 2 +- verilogae/verilogae/src/opts.rs | 22 +- verilogae/verilogae_ffi/src/ffi/generated.rs | 4 +- verilogae/verilogae_ffi/src/tests.rs | 2 +- verilogae/verilogae_py/Cargo.toml | 2 +- verilogae/verilogae_py/src/ffi.rs | 18 +- verilogae/verilogae_py/src/lib.rs | 6 +- verilogae/verilogae_py/src/model.rs | 17 +- 45 files changed, 3281 insertions(+), 1408 deletions(-) diff --git a/.gitignore b/.gitignore index 979a0e0..9a1238c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ markus_notes !.vscode/launch-openvaf*.json *~ /target_0.3/ +.aider* +.env +**.swp diff --git a/Cargo.lock b/Cargo.lock index ec9b6a6..fe8c99a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -159,7 +159,7 @@ version = "1.0.0" name = "basedb" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "arena", "codespan-reporting", "expect-test", @@ -473,7 +473,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", ] [[package]] @@ -482,7 +482,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "allocator-api2", ] @@ -533,7 +533,7 @@ dependencies = [ name = "hir_def" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "arena", "basedb", "expect-test", @@ -551,7 +551,7 @@ dependencies = [ name = "hir_lower" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "basedb", "bitset", "expect-test", @@ -573,7 +573,7 @@ dependencies = [ name = "hir_ty" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "arena", "basedb", "hir_def", @@ -646,10 +646,16 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4644821e1c3d7a560fe13d842d13f587c07348a1a05d3a797152d41c90c56df2" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "hashbrown 0.13.2", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "lexer" version = "0.0.0" @@ -709,12 +715,17 @@ dependencies = [ ] [[package]] -name = "llvm" -version = "0.0.0" +name = "llvm-sys" +version = "181.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320f9d2723c97d4b78f9190a61ed25cc7cfbe456668c08e6e7dd8e50ceb8500" dependencies = [ - "ahash 0.8.6", + "anyhow", "cc", + "lazy_static", "libc", + "regex-lite", + "semver", ] [[package]] @@ -743,7 +754,7 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" name = "melange-core" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "anyhow", "bitflags 2.4.1", "camino", @@ -807,7 +818,7 @@ dependencies = [ name = "mir" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "bforest", "bitset", "dot", @@ -824,7 +835,7 @@ dependencies = [ name = "mir_autodiff" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "arena", "bitset", "expect-test", @@ -867,15 +878,16 @@ dependencies = [ name = "mir_llvm" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "arrayvec", "base_n", "lasso", "libc", - "llvm", + "llvm-sys", "log", "mir", "target", + "target-lexicon", "typed-index-collections", ] @@ -883,7 +895,7 @@ dependencies = [ name = "mir_opt" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "bitset", "expect-test", "hashbrown 0.14.2", @@ -969,7 +981,7 @@ dependencies = [ "libc", "libloading", "linker", - "llvm", + "llvm-sys", "md5", "mini_harness", "mir_llvm", @@ -1007,7 +1019,7 @@ dependencies = [ name = "osdi" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "base_n", "camino", "expect-test", @@ -1016,7 +1028,7 @@ dependencies = [ "hir_lower", "indexmap 2.0.2", "lasso", - "llvm", + "llvm-sys", "log", "mini_harness", "mir", @@ -1092,7 +1104,7 @@ version = "0.0.0" name = "preprocessor" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "expect-test", "lexer", "stdx", @@ -1198,6 +1210,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "rowan" version = "0.15.13" @@ -1278,11 +1296,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "sim_back" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "bitset", "cov-mark", "expect-test", @@ -1320,7 +1344,7 @@ checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" name = "sourcegen" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "indexmap 2.0.2", "proc-macro2", "quote", @@ -1442,7 +1466,7 @@ checksum = "183496e014253d15abbe6235677b1392dba2d40524c88938991226baa38ac7c4" name = "typed_indexmap" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "indexmap 2.0.2", ] @@ -1480,7 +1504,7 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" name = "verilogae" version = "1.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "anyhow", "base_n", "basedb", @@ -1493,7 +1517,7 @@ dependencies = [ "lasso", "libloading", "linker", - "llvm", + "llvm-sys", "md5", "mir", "mir_autodiff", @@ -1538,7 +1562,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" name = "vfs" version = "0.0.0" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "chardetng", "encoding_rs", "indexmap 2.0.2", @@ -1698,18 +1722,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.15" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.15" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/openvaf/hir/Cargo.toml b/openvaf/hir/Cargo.toml index dec60bf..ab6f7e7 100644 --- a/openvaf/hir/Cargo.toml +++ b/openvaf/hir/Cargo.toml @@ -30,7 +30,7 @@ salsa = "0.17.0-pre.2" typed-index-collections = "3.1" anyhow = "1" -smol_str = { version = "0.2", default_features=false } +smol_str = { version = "0.2", default-features=false } parking_lot = "0.12" [dev-dependencies] diff --git a/openvaf/mir_llvm/src/builder.rs b/openvaf/mir_llvm/src/builder.rs index d1a3ccb..964beb8 100644 --- a/openvaf/mir_llvm/src/builder.rs +++ b/openvaf/mir_llvm/src/builder.rs @@ -2,10 +2,7 @@ use std::slice; use arrayvec::ArrayVec; use libc::c_uint; -use llvm::{ - LLVMBuildExtractValue, LLVMBuildICmp, LLVMBuildLoad2, LLVMBuildStore, LLVMGetReturnType, - UNNAMED, -}; +use llvm_sys::core::LLVMBuildExtractValue; use mir::{ Block, ControlFlowGraph, FuncRef, Function, Inst, Opcode, Param, PhiNode, Value, ValueDef, F_ZERO, ZERO, @@ -13,21 +10,21 @@ use mir::{ use typed_index_collections::TiVec; use crate::callbacks::CallbackFun; -use crate::CodegenCx; +use crate::{CodegenCx, UNNAMED}; #[derive(Clone)] pub struct MemLoc<'ll> { - pub ptr: &'ll llvm::Value, - pub ptr_ty: &'ll llvm::Type, - pub ty: &'ll llvm::Type, - pub indices: Box<[&'ll llvm::Value]>, + pub ptr: &'ll llvm_sys::LLVMValue, + pub ptr_ty: &'ll llvm_sys::LLVMType, + pub ty: &'ll llvm_sys::LLVMType, + pub indices: Box<[&'ll llvm_sys::LLVMValue]>, } impl<'ll> MemLoc<'ll> { pub fn struct_gep( - ptr: &'ll llvm::Value, - ptr_ty: &'ll llvm::Type, - ty: &'ll llvm::Type, + ptr: &'ll llvm_sys::LLVMValue, + ptr_ty: &'ll llvm_sys::LLVMType, + ty: &'ll llvm_sys::LLVMType, idx: u32, cx: &CodegenCx<'_, 'll>, ) -> MemLoc<'ll> { @@ -41,8 +38,11 @@ impl<'ll> MemLoc<'ll> { /// # Safety /// /// ptr_ty, ty and indices must be valid for ptr - pub unsafe fn read(&self, llbuilder: &llvm::Builder<'ll>) -> &'ll llvm::Value { - self.read_with_ptr(llbuilder, self.ptr) + pub unsafe fn read(&self, llbuilder: &llvm_sys::LLVMBuilder) -> &'ll llvm_sys::LLVMValue { + // Convert references to raw pointers + + // Call read_with_ptr and convert the result back to a reference + &*(self.read_with_ptr(NonNull::from(llbuilder).as_ptr(), NonNull::from(self.ptr).as_ptr())) } /// # Safety @@ -50,18 +50,21 @@ impl<'ll> MemLoc<'ll> { /// ptr_ty, ty and indices must be valid for ptr pub unsafe fn read_with_ptr( &self, - llbuilder: &llvm::Builder<'ll>, - ptr: &'ll llvm::Value, - ) -> &'ll llvm::Value { + llbuilder: *mut llvm_sys::LLVMBuilder, + ptr: *mut llvm_sys::LLVMValue, + ) -> *mut llvm_sys::LLVMValue { let ptr = self.to_ptr_from(llbuilder, ptr); - LLVMBuildLoad2(llbuilder, self.ty, ptr, UNNAMED) + // SAFETY: We're calling an unsafe LLVM function and trusting that it returns a valid value + unsafe { + llvm_sys::core::LLVMBuildLoad2(llbuilder, self.ty as *const _ as *mut _, ptr, UNNAMED) + } } /// # Safety /// /// ptr_ty and indices must be valid for ptr - pub unsafe fn to_ptr(&self, llbuilder: &llvm::Builder<'ll>) -> &'ll llvm::Value { - self.to_ptr_from(llbuilder, self.ptr) + pub unsafe fn to_ptr(&self, llbuilder: *mut llvm_sys::LLVMBuilder) -> *mut llvm_sys::LLVMValue { + self.to_ptr_from(llbuilder, self.ptr as *const _ as *mut _) } /// # Safety @@ -69,15 +72,15 @@ impl<'ll> MemLoc<'ll> { /// ptr_ty and indices must be valid for ptr pub unsafe fn to_ptr_from( &self, - llbuilder: &llvm::Builder<'ll>, - mut ptr: &'ll llvm::Value, - ) -> &'ll llvm::Value { + llbuilder: *mut llvm_sys::LLVMBuilder, + mut ptr: *mut llvm_sys::LLVMValue, + ) -> *mut llvm_sys::LLVMValue { if !self.indices.is_empty() { - ptr = llvm::LLVMBuildGEP2( + ptr = llvm_sys::core::LLVMBuildGEP2( llbuilder, - self.ptr_ty, + self.ptr_ty as *const _ as *mut _, ptr, - self.indices.as_ptr(), + self.indices.as_ptr() as *mut *mut _, self.indices.len() as u32, UNNAMED, ); @@ -95,13 +98,13 @@ impl<'ll> From> for BuilderVal<'ll> { #[derive(Clone)] pub enum BuilderVal<'ll> { Undef, - Eager(&'ll llvm::Value), + Eager(&'ll llvm_sys::LLVMValue), Load(Box>), Call(Box>), } -impl<'ll> From<&'ll llvm::Value> for BuilderVal<'ll> { - fn from(val: &'ll llvm::Value) -> Self { +impl<'ll> From<&'ll llvm_sys::LLVMValue> for BuilderVal<'ll> { + fn from(val: &'ll llvm_sys::LLVMValue) -> Self { BuilderVal::Eager(val) } } @@ -110,7 +113,7 @@ impl<'ll> BuilderVal<'ll> { /// # Safety /// /// For Self::Load and Self::Call, the values must be valid - pub unsafe fn get(&self, builder: &Builder<'_, '_, 'll>) -> &'ll llvm::Value { + pub unsafe fn get(&self, builder: &Builder<'_, '_, 'll>) -> &'ll llvm_sys::LLVMValue { match self { BuilderVal::Undef => unreachable!("attempted to read undefined value"), BuilderVal::Eager(val) => val, @@ -122,12 +125,21 @@ impl<'ll> BuilderVal<'ll> { /// # Safety /// /// For Self::Load and Self::Call, the values must be valid - pub unsafe fn get_ty(&self, builder: &Builder<'_, '_, 'll>) -> Option<&'ll llvm::Type> { + pub unsafe fn get_ty(&self, builder: &Builder<'_, '_, 'll>) -> Option<&'ll llvm_sys::LLVMType> { let ty = match self { BuilderVal::Undef => return None, BuilderVal::Eager(val) => builder.cx.val_ty(val), BuilderVal::Load(loc) => loc.ty, - BuilderVal::Call(call) => LLVMGetReturnType(call.fun_ty), + BuilderVal::Call(call) => { + // SAFETY: We're converting a reference to a raw pointer, then calling an LLVM function, + // and finally converting the result back to a reference. This is safe as long as LLVM + // behaves correctly and the input type is valid. + unsafe { + let fun_ty_ptr = call.fun_ty as *const _ as llvm_sys::prelude::LLVMTypeRef; + let return_ty_ptr = llvm_sys::core::LLVMGetReturnType(fun_ty_ptr); + &*return_ty_ptr + } + } }; Some(ty) } @@ -136,22 +148,22 @@ impl<'ll> BuilderVal<'ll> { // All Builders must have an llfn associated with them #[must_use] pub struct Builder<'a, 'cx, 'll> { - pub llbuilder: &'a mut llvm::Builder<'ll>, + pub llbuilder: &'a mut llvm_sys::LLVMBuilder, pub cx: &'a CodegenCx<'cx, 'll>, pub func: &'a Function, - pub blocks: TiVec>, + pub blocks: TiVec>, pub values: TiVec>, pub params: TiVec>, pub callbacks: TiVec>>, - pub prepend_pos: &'ll llvm::BasicBlock, - pub unfinished_phis: Vec<(PhiNode, &'ll llvm::Value)>, - pub fun: &'ll llvm::Value, + pub prepend_pos: &'ll llvm_sys::LLVMBasicBlock, + pub unfinished_phis: Vec<(PhiNode, &'ll llvm_sys::LLVMValue)>, + pub fun: &'ll llvm_sys::LLVMValue, } impl Drop for Builder<'_, '_, '_> { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _)); + llvm_sys::core::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _)); } } } @@ -161,43 +173,60 @@ pub enum FastMathMode { Partial, Disabled, } - impl<'a, 'cx, 'll> Builder<'a, 'cx, 'll> { pub fn new( cx: &'a CodegenCx<'cx, 'll>, mir_func: &'a Function, - llfunc: &'ll llvm::Value, + llfunc: &'ll llvm_sys::LLVMValue, ) -> Self { - let entry = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED) }; - let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) }; + let entry = unsafe { + llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ) + }; + let llbuilder = + unsafe { llvm_sys::core::LLVMCreateBuilderInContext(cx.llcx as *const _ as *mut _) }; let mut blocks: TiVec<_, _> = vec![None; mir_func.layout.num_blocks()].into(); for bb in mir_func.layout.blocks() { - blocks[bb] = - unsafe { Some(llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED)) }; + blocks[bb] = unsafe { + Some(llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ) as *mut _) + }; } - unsafe { llvm::LLVMPositionBuilderAtEnd(llbuilder, entry) }; + unsafe { llvm_sys::core::LLVMPositionBuilderAtEnd(llbuilder, entry) }; Builder { - llbuilder, + llbuilder: unsafe { &mut *llbuilder }, cx, func: mir_func, - blocks, + blocks: blocks.into_iter().map(|b| b.map(|ptr| unsafe { &*ptr })).collect(), values: vec![BuilderVal::Undef; mir_func.dfg.num_values()].into(), params: Default::default(), callbacks: Default::default(), fun: llfunc, - prepend_pos: entry, + prepend_pos: unsafe { &*entry }, unfinished_phis: Vec::new(), } } } +use std::ptr::NonNull; + impl<'ll> Builder<'_, '_, 'll> { /// # Safety /// Must not be called when a block that already contains a terminator is selected /// Must be called in the entry block of the function - pub unsafe fn alloca(&self, ty: &'ll llvm::Type) -> &'ll llvm::Value { - llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED) + pub unsafe fn alloca(&self, ty: &'ll llvm_sys::LLVMType) -> &'ll llvm_sys::LLVMValue { + &*(llvm_sys::core::LLVMBuildAlloca( + self.llbuilder as *const _ as *mut _, + ty as *const _ as *mut _, + UNNAMED, + ) as *const _) } /// # Safety @@ -205,72 +234,110 @@ impl<'ll> Builder<'_, '_, 'll> { /// Their return types must match and cond must be a bool pub unsafe fn add_branching_select( &mut self, - cond: &'ll llvm::Value, - build_then: impl FnOnce(&mut Self) -> &'ll llvm::Value, - build_else: impl FnOnce(&mut Self) -> &'ll llvm::Value, - ) -> &'ll llvm::Value { + cond: &'ll llvm_sys::LLVMValue, + build_then: impl FnOnce(&mut Self) -> &'ll llvm_sys::LLVMValue, + build_else: impl FnOnce(&mut Self) -> &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { let start = self.prepend_pos; - let exit = llvm::LLVMAppendBasicBlockInContext(self.cx.llcx, self.fun, UNNAMED); - let then_bb = llvm::LLVMAppendBasicBlockInContext(self.cx.llcx, self.fun, UNNAMED); - llvm::LLVMPositionBuilderAtEnd(self.llbuilder, then_bb); - self.prepend_pos = then_bb; + let exit = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.cx.llcx).as_ptr(), + NonNull::from(self.fun).as_ptr(), + UNNAMED, + ); + let then_bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.cx.llcx).as_ptr(), + NonNull::from(self.fun).as_ptr(), + UNNAMED, + ); + llvm_sys::core::LLVMPositionBuilderAtEnd(self.llbuilder, then_bb); + self.prepend_pos = &*(then_bb as *const _); let then_val = build_then(self); - llvm::LLVMBuildBr(self.llbuilder, exit); + llvm_sys::core::LLVMBuildBr(self.llbuilder, exit); - let else_bb = llvm::LLVMAppendBasicBlockInContext(self.cx.llcx, self.fun, UNNAMED); - llvm::LLVMPositionBuilderAtEnd(self.llbuilder, else_bb); - self.prepend_pos = else_bb; + let else_bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.cx.llcx).as_ptr(), + NonNull::from(self.fun).as_ptr(), + UNNAMED, + ); + llvm_sys::core::LLVMPositionBuilderAtEnd(self.llbuilder, else_bb); + self.prepend_pos = &*(else_bb as *const _); let else_val = build_else(self); - llvm::LLVMBuildBr(self.llbuilder, exit); + llvm_sys::core::LLVMBuildBr(self.llbuilder, exit); - llvm::LLVMPositionBuilderAtEnd(self.llbuilder, start); - llvm::LLVMBuildCondBr(self.llbuilder, cond, then_bb, else_bb); + llvm_sys::core::LLVMPositionBuilderAtEnd(self.llbuilder, NonNull::from(start).as_ptr()); + llvm_sys::core::LLVMBuildCondBr( + self.llbuilder, + NonNull::from(cond).as_ptr(), + then_bb, + else_bb, + ); - self.prepend_pos = exit; - llvm::LLVMPositionBuilderAtEnd(self.llbuilder, self.prepend_pos); - let phi = llvm::LLVMBuildPhi(self.llbuilder, llvm::LLVMTypeOf(then_val), UNNAMED); - llvm::LLVMAddIncoming(phi, [then_val, else_val].as_ptr(), [then_bb, else_bb].as_ptr(), 2); - phi + self.prepend_pos = &*(exit as *const _); + llvm_sys::core::LLVMPositionBuilderAtEnd(self.llbuilder, exit); + let phi = llvm_sys::core::LLVMBuildPhi( + self.llbuilder, + llvm_sys::core::LLVMTypeOf(NonNull::from(then_val).as_ptr()), + UNNAMED, + ); + let mut incoming_blocks = [then_bb, else_bb]; + llvm_sys::core::LLVMAddIncoming( + phi, + [NonNull::from(then_val).as_ptr(), NonNull::from(else_val).as_ptr()].as_ptr() as *mut _, + incoming_blocks.as_mut_ptr(), + 2, + ); + &*phi } /// # Safety /// Only correct llvm api calls must be performed within build_then and build_else /// Their return types must match and cond must be a bool pub unsafe fn select( - &self, - cond: &'ll llvm::Value, - then_val: &'ll llvm::Value, - else_val: &'ll llvm::Value, - ) -> &'ll llvm::Value { - llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) + &mut self, + cond: &'ll llvm_sys::LLVMValue, + then_val: &'ll llvm_sys::LLVMValue, + else_val: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { + let result = llvm_sys::core::LLVMBuildSelect( + self.llbuilder, + NonNull::from(cond).as_ptr(), + NonNull::from(then_val).as_ptr(), + NonNull::from(else_val).as_ptr(), + UNNAMED, + ); + &*(result as *const _) } /// # Safety /// Must not be called when a block that already contains a terminator is selected pub unsafe fn typed_gep( - &self, - arr_ty: &'ll llvm::Type, - ptr: &'ll llvm::Value, - indices: &[&'ll llvm::Value], - ) -> &'ll llvm::Value { - llvm::LLVMBuildGEP2( + &mut self, + arr_ty: &'ll llvm_sys::LLVMType, + ptr: &'ll llvm_sys::LLVMValue, + indices: &[&'ll llvm_sys::LLVMValue], + ) -> &'ll llvm_sys::LLVMValue { + let result = llvm_sys::core::LLVMBuildGEP2( self.llbuilder, - arr_ty, - ptr, - indices.as_ptr(), + NonNull::from(arr_ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + indices.as_ptr() as *const _ as *mut _, indices.len() as u32, UNNAMED, - ) + ); + + // Safety: We're assuming that the LLVM API returns a valid pointer. + // The lifetime 'll is tied to the Builder, which owns the LLVM context. + NonNull::new(result).map(|nn| nn.as_ref()).expect("LLVM returned null pointer") } /// # Safety /// Must not be called when a block that already contains a terminator is selected pub unsafe fn gep( - &self, - elem_ty: &'ll llvm::Type, - ptr: &'ll llvm::Value, - indices: &[&'ll llvm::Value], - ) -> &'ll llvm::Value { + &mut self, + elem_ty: &'ll llvm_sys::LLVMType, + ptr: &'ll llvm_sys::LLVMValue, + indices: &[&'ll llvm_sys::LLVMValue], + ) -> &'ll llvm_sys::LLVMValue { self.typed_gep(elem_ty, ptr, indices) } @@ -278,32 +345,48 @@ impl<'ll> Builder<'_, '_, 'll> { /// * Must not be called when a block that already contains a terminator is selected /// * struct_ty must be a valid struct type for this pointer and idx must be in bounds pub unsafe fn struct_gep( - &self, - struct_ty: &'ll llvm::Type, - ptr: &'ll llvm::Value, + &mut self, + struct_ty: &'ll llvm_sys::LLVMType, + ptr: &'ll llvm_sys::LLVMValue, idx: u32, - ) -> &'ll llvm::Value { - llvm::LLVMBuildStructGEP2(self.llbuilder, struct_ty, ptr, idx, UNNAMED) + ) -> &'ll llvm_sys::LLVMValue { + let result = llvm_sys::core::LLVMBuildStructGEP2( + self.llbuilder, + NonNull::from(struct_ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + idx, + UNNAMED, + ); + + // Safety: We're assuming that the LLVM API returns a valid pointer. + // The lifetime 'll is tied to the Builder, which owns the LLVM context. + NonNull::new(result).map(|nn| nn.as_ref()).expect("LLVM returned null pointer") } /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn fat_ptr_get_ptr(&self, ptr: &'ll llvm::Value) -> &'ll llvm::Value { + pub unsafe fn fat_ptr_get_ptr( + &mut self, + ptr: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { self.struct_gep(self.cx.ty_fat_ptr(), ptr, 0) } /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn fat_ptr_get_meta(&self, ptr: &'ll llvm::Value) -> &'ll llvm::Value { + pub unsafe fn fat_ptr_get_meta( + &mut self, + ptr: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { self.struct_gep(self.cx.ty_fat_ptr(), ptr, 1) } /// # Safety /// Must not be called when a block that already contains a terminator is selected pub unsafe fn fat_ptr_to_parts( - &self, - ptr: &'ll llvm::Value, - ) -> (&'ll llvm::Value, &'ll llvm::Value) { + &mut self, + ptr: &'ll llvm_sys::LLVMValue, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMValue) { (self.fat_ptr_get_ptr(ptr), self.fat_ptr_get_meta(ptr)) } @@ -311,23 +394,23 @@ impl<'ll> Builder<'_, '_, 'll> { /// * Must not be called when a block that already contains a terminator is selected pub unsafe fn call( &self, - fun_ty: &'ll llvm::Type, - fun: &'ll llvm::Value, - operands: &[&'ll llvm::Value], - ) -> &'ll llvm::Value { - let res = llvm::LLVMBuildCall2( - self.llbuilder, - fun_ty, - fun, - operands.as_ptr(), + fun_ty: &'ll llvm_sys::LLVMType, + fun: &'ll llvm_sys::LLVMValue, + operands: &[&'ll llvm_sys::LLVMValue], + ) -> &'ll llvm_sys::LLVMValue { + let res = llvm_sys::core::LLVMBuildCall2( + self.llbuilder as *const _ as *mut _, + NonNull::from(fun_ty).as_ptr(), + NonNull::from(fun).as_ptr(), + operands.as_ptr() as *mut _, operands.len() as u32, UNNAMED, ); // forgett this is a real footgun - let cconv = llvm::LLVMGetFunctionCallConv(fun); - llvm::LLVMSetInstructionCallConv(res, cconv); - res + let cconv = llvm_sys::core::LLVMGetFunctionCallConv(NonNull::from(fun).as_ptr()); + llvm_sys::core::LLVMSetInstructionCallConv(res, cconv); + &*(res as *const _) } pub fn build_consts(&mut self) { @@ -348,7 +431,10 @@ impl<'ll> Builder<'_, '_, 'll> { /// called twice) pub unsafe fn build_func(&mut self) { let entry = self.func.layout.entry_block().unwrap(); - llvm::LLVMBuildBr(self.llbuilder, self.blocks[entry].unwrap()); + llvm_sys::core::LLVMBuildBr( + self.llbuilder, + NonNull::from(self.blocks[entry].unwrap()).as_ptr(), + ); let mut cfg = ControlFlowGraph::new(); cfg.compute(self.func); let po: Vec<_> = cfg.postorder(self.func).collect(); @@ -368,26 +454,38 @@ impl<'ll> Builder<'_, '_, 'll> { }) .unzip(); - llvm::LLVMAddIncoming(llval, vals.as_ptr(), blocks.as_ptr(), vals.len() as c_uint); + let mut incoming_vals: Vec<*mut llvm_sys::LLVMValue> = + vals.iter().map(|&v| NonNull::from(v).as_ptr()).collect(); + let mut incoming_blocks: Vec<*mut llvm_sys::LLVMBasicBlock> = + blocks.iter().map(|&b| NonNull::from(b).as_ptr()).collect(); + + llvm_sys::core::LLVMAddIncoming( + NonNull::from(*llval).as_ptr(), + incoming_vals.as_mut_ptr(), + incoming_blocks.as_mut_ptr(), + vals.len() as c_uint, + ); } self.unfinished_phis.clear(); } - pub fn select_bb(&self, bb: Block) { unsafe { - llvm::LLVMPositionBuilderAtEnd(self.llbuilder, self.blocks[bb].unwrap()); + llvm_sys::core::LLVMPositionBuilderAtEnd( + self.llbuilder as *const _ as *mut _, + NonNull::from(self.blocks[bb].unwrap()).as_ptr(), + ); } } pub fn select_bb_before_terminator(&self, bb: Block) { let bb = self.blocks[bb].unwrap(); unsafe { - let inst = llvm::LLVMGetLastInstruction(bb); - llvm::LLVMPositionBuilder(self.llbuilder, bb, inst); - }; + let bb_ptr = NonNull::from(bb).as_ptr(); + let inst = llvm_sys::core::LLVMGetLastInstruction(bb_ptr); + llvm_sys::core::LLVMPositionBuilder(self.llbuilder as *const _ as *mut _, bb_ptr, inst); + } } - /// # Safety /// /// Must not be called if any non phi instruction has already been build for `bb` @@ -407,15 +505,14 @@ impl<'ll> Builder<'_, '_, 'll> { /// # Safety /// must not be called multiple times /// a terminator must not be build for the exit bb trough other means - pub unsafe fn ret(&mut self, val: &'ll llvm::Value) { - llvm::LLVMBuildRet(self.llbuilder, val); + pub unsafe fn ret(&mut self, val: &'ll llvm_sys::LLVMValue) { + llvm_sys::core::LLVMBuildRet(self.llbuilder, NonNull::from(val).as_ptr()); } - /// # Safety /// must not be called multiple times /// a terminator must not be build for the exit bb trough other means pub unsafe fn ret_void(&mut self) { - llvm::LLVMBuildRetVoid(self.llbuilder); + llvm_sys::core::LLVMBuildRetVoid(self.llbuilder as *mut _); } /// # Safety @@ -427,11 +524,11 @@ impl<'ll> Builder<'_, '_, 'll> { mir::InstructionData::Unary { opcode, ref arg } => (opcode, slice::from_ref(arg)), mir::InstructionData::Binary { opcode, ref args } => (opcode, args.as_slice()), mir::InstructionData::Branch { cond, then_dst, else_dst, .. } => { - llvm::LLVMBuildCondBr( - self.llbuilder, - self.values[cond].get(self), - self.blocks[then_dst].unwrap(), - self.blocks[else_dst].unwrap(), + llvm_sys::core::LLVMBuildCondBr( + self.llbuilder as *const _ as *mut _, + NonNull::from(self.values[cond].get(self)).as_ptr(), + NonNull::from(self.blocks[then_dst].unwrap()).as_ptr(), + NonNull::from(self.blocks[else_dst].unwrap()).as_ptr(), ); return; } @@ -443,14 +540,22 @@ impl<'ll> Builder<'_, '_, 'll> { .phi_edges(phi) .find_map(|(_, val)| self.values[val].get_ty(self)) .unwrap(); - let llval = llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED); - self.unfinished_phis.push((phi.clone(), llval)); + let llval = llvm_sys::core::LLVMBuildPhi( + self.llbuilder, + NonNull::from(ty).as_ptr(), + UNNAMED, + ); + let llval_ref: &'ll llvm_sys::LLVMValue = &*(llval as *const _); + self.unfinished_phis.push((phi.clone(), llval_ref)); let res = self.func.dfg.first_result(inst); - self.values[res] = llval.into(); + self.values[res] = BuilderVal::Eager(llval_ref); return; } mir::InstructionData::Jump { destination } => { - llvm::LLVMBuildBr(self.llbuilder, self.blocks[destination].unwrap()); + llvm_sys::core::LLVMBuildBr( + self.llbuilder, + NonNull::from(self.blocks[destination].unwrap()).as_ptr(), + ); return; } mir::InstructionData::Call { func_ref, ref args } => { @@ -487,9 +592,14 @@ impl<'ll> Builder<'_, '_, 'll> { [val] => self.values[*val] = res.into(), vals => { for (i, val) in vals.iter().enumerate() { - let res = - LLVMBuildExtractValue(self.llbuilder, res, i as u32, UNNAMED); - self.values[*val] = res.into(); + let res = LLVMBuildExtractValue( + self.llbuilder, + NonNull::from(res).as_ptr(), + i as u32, + UNNAMED, + ); + let res_ref: &'ll llvm_sys::LLVMValue = &*(res as *const _); + self.values[*val] = BuilderVal::Eager(res_ref); } } } @@ -500,92 +610,114 @@ impl<'ll> Builder<'_, '_, 'll> { let val = match opcode { Opcode::Inot | Opcode::Bnot => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildNot(self.llbuilder, arg, UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildNot(self.llbuilder, arg, UNNAMED) } Opcode::Ineg => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildNeg(self.llbuilder, arg, UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildNeg(self.llbuilder, arg, UNNAMED) } Opcode::Fneg => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildFNeg(self.llbuilder, arg, UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFNeg(self.llbuilder, arg, UNNAMED) } Opcode::IFcast => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildSIToFP(self.llbuilder, arg, self.cx.ty_double(), UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildSIToFP( + self.llbuilder, + arg, + NonNull::from(self.cx.ty_double()).as_ptr(), + UNNAMED, + ) } Opcode::BFcast => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildUIToFP(self.llbuilder, arg, self.cx.ty_double(), UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildUIToFP( + self.llbuilder, + arg, + NonNull::from(self.cx.ty_double()).as_ptr(), + UNNAMED, + ) } Opcode::BIcast => { - let arg = self.values[args[0]].get(self); - llvm::LLVMBuildIntCast2(self.llbuilder, arg, self.cx.ty_int(), llvm::False, UNNAMED) + let arg = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildIntCast2( + self.llbuilder, + arg, + NonNull::from(self.cx.ty_int()).as_ptr(), + 0, + UNNAMED, + ) } - Opcode::IBcast => self.build_int_cmp(&[args[0], ZERO], llvm::IntPredicate::IntNE), - Opcode::FBcast => self.build_real_cmp(&[args[0], F_ZERO], llvm::RealPredicate::RealONE), + Opcode::IBcast => NonNull::from( + self.build_int_cmp(&[args[0], ZERO], llvm_sys::LLVMIntPredicate::LLVMIntNE), + ) + .as_ptr(), + Opcode::FBcast => NonNull::from( + self.build_real_cmp(&[args[0], F_ZERO], llvm_sys::LLVMRealPredicate::LLVMRealONE), + ) + .as_ptr(), Opcode::Iadd => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildAdd(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Isub => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildSub(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Imul => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildMul(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Idiv => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildSDiv(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Irem => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildSRem(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Ishl => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildShl(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Ishr => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildLShr(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Ixor => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildXor(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Iand => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildAnd(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Ior => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildOr(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Fadd => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Fsub => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Fmul => { if matches!(self.values[args[0]], BuilderVal::Undef) { @@ -595,67 +727,105 @@ impl<'ll> Builder<'_, '_, 'll> { self.func.layout.inst_block(inst).unwrap() ); } - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Fdiv => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED) + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED) } Opcode::Frem => { - let lhs = self.values[args[0]].get(self); - let rhs = self.values[args[1]].get(self); - llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED) - } - Opcode::Ilt => self.build_int_cmp(args, llvm::IntPredicate::IntSLT), - Opcode::Igt => self.build_int_cmp(args, llvm::IntPredicate::IntSGT), - Opcode::Flt => self.build_real_cmp(args, llvm::RealPredicate::RealOLT), - Opcode::Fgt => self.build_real_cmp(args, llvm::RealPredicate::RealOGT), - Opcode::Ile => self.build_int_cmp(args, llvm::IntPredicate::IntSLE), - Opcode::Ige => self.build_int_cmp(args, llvm::IntPredicate::IntSGE), - Opcode::Fle => self.build_real_cmp(args, llvm::RealPredicate::RealOLE), - Opcode::Fge => self.build_real_cmp(args, llvm::RealPredicate::RealOGE), - Opcode::Ieq | Opcode::Beq => self.build_int_cmp(args, llvm::IntPredicate::IntEQ), - Opcode::Feq => self.build_real_cmp(args, llvm::RealPredicate::RealOEQ), - Opcode::Fne => self.build_real_cmp(args, llvm::RealPredicate::RealONE), - Opcode::Bne | Opcode::Ine => self.build_int_cmp(args, llvm::IntPredicate::IntNE), - Opcode::FIcast => self.intrinsic(args, "llvm.lround.i32.f64"), - Opcode::Seq => self.strcmp(args, false), - Opcode::Sne => self.strcmp(args, true), - Opcode::Sqrt => self.intrinsic(args, "llvm.sqrt.f64"), - Opcode::Exp => self.intrinsic(args, "llvm.exp.f64"), - Opcode::Ln => self.intrinsic(args, "llvm.log.f64"), - Opcode::Log => self.intrinsic(args, "llvm.log10.f64"), + let lhs = NonNull::from(self.values[args[0]].get(self)).as_ptr(); + let rhs = NonNull::from(self.values[args[1]].get(self)).as_ptr(); + llvm_sys::core::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED) + } + Opcode::Ilt => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntSLT)) + .as_ptr() + } + Opcode::Igt => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntSGT)) + .as_ptr() + } + Opcode::Flt => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealOLT)) + .as_ptr() + } + Opcode::Fgt => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealOGT)) + .as_ptr() + } + Opcode::Ile => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntSLE)) + .as_ptr() + } + Opcode::Ige => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntSGE)) + .as_ptr() + } + Opcode::Fle => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealOLE)) + .as_ptr() + } + Opcode::Fge => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealOGE)) + .as_ptr() + } + Opcode::Ieq | Opcode::Beq => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntEQ)) + .as_ptr() + } + Opcode::Feq => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealOEQ)) + .as_ptr() + } + Opcode::Fne => { + NonNull::from(self.build_real_cmp(args, llvm_sys::LLVMRealPredicate::LLVMRealONE)) + .as_ptr() + } + Opcode::Bne | Opcode::Ine => { + NonNull::from(self.build_int_cmp(args, llvm_sys::LLVMIntPredicate::LLVMIntNE)) + .as_ptr() + } + Opcode::FIcast => NonNull::from(self.intrinsic(args, "llvm.lround.i32.f64")).as_ptr(), + Opcode::Seq => NonNull::from(self.strcmp(args, false)).as_ptr(), + Opcode::Sne => NonNull::from(self.strcmp(args, true)).as_ptr(), + Opcode::Sqrt => NonNull::from(self.intrinsic(args, "llvm.sqrt.f64")).as_ptr(), + Opcode::Exp => NonNull::from(self.intrinsic(args, "llvm.exp.f64")).as_ptr(), + Opcode::Ln => NonNull::from(self.intrinsic(args, "llvm.log.f64")).as_ptr(), + Opcode::Log => NonNull::from(self.intrinsic(args, "llvm.log10.f64")).as_ptr(), Opcode::Clog2 => { - let leading_zeros = self.intrinsic(&[args[0], true.into()], "llvm.ctlz"); - let total_bits = self.cx.const_int(32); - llvm::LLVMBuildSub(self.llbuilder, total_bits, leading_zeros, UNNAMED) - } - Opcode::Floor => self.intrinsic(args, "llvm.floor.f64"), - Opcode::Ceil => self.intrinsic(args, "llvm.ceil.f64"), - Opcode::Sin => self.intrinsic(args, "llvm.sin.f64"), - Opcode::Cos => self.intrinsic(args, "llvm.cos.f64"), - Opcode::Tan => self.intrinsic(args, "tan"), - Opcode::Hypot => self.intrinsic(args, "hypot"), - Opcode::Asin => self.intrinsic(args, "asin"), - Opcode::Acos => self.intrinsic(args, "acos"), - Opcode::Atan => self.intrinsic(args, "atan"), - Opcode::Atan2 => self.intrinsic(args, "atan2"), - Opcode::Sinh => self.intrinsic(args, "sinh"), - Opcode::Cosh => self.intrinsic(args, "cosh"), - Opcode::Tanh => self.intrinsic(args, "tanh"), - Opcode::Asinh => self.intrinsic(args, "asinh"), - Opcode::Acosh => self.intrinsic(args, "acosh"), - Opcode::Atanh => self.intrinsic(args, "atanh"), - Opcode::Pow => self.intrinsic(args, "llvm.pow.f64"), - Opcode::OptBarrier => self.values[args[0]].get(self), + let leading_zeros = + NonNull::from(self.intrinsic(&[args[0], true.into()], "llvm.ctlz")).as_ptr(); + let total_bits = NonNull::from(self.cx.const_int(32)).as_ptr(); + llvm_sys::core::LLVMBuildSub(self.llbuilder, total_bits, leading_zeros, UNNAMED) + } + Opcode::Floor => NonNull::from(self.intrinsic(args, "llvm.floor.f64")).as_ptr(), + Opcode::Ceil => NonNull::from(self.intrinsic(args, "llvm.ceil.f64")).as_ptr(), + Opcode::Sin => NonNull::from(self.intrinsic(args, "llvm.sin.f64")).as_ptr(), + Opcode::Cos => NonNull::from(self.intrinsic(args, "llvm.cos.f64")).as_ptr(), + Opcode::Tan => NonNull::from(self.intrinsic(args, "tan")).as_ptr(), + Opcode::Hypot => NonNull::from(self.intrinsic(args, "hypot")).as_ptr(), + Opcode::Asin => NonNull::from(self.intrinsic(args, "asin")).as_ptr(), + Opcode::Acos => NonNull::from(self.intrinsic(args, "acos")).as_ptr(), + Opcode::Atan => NonNull::from(self.intrinsic(args, "atan")).as_ptr(), + Opcode::Atan2 => NonNull::from(self.intrinsic(args, "atan2")).as_ptr(), + Opcode::Sinh => NonNull::from(self.intrinsic(args, "sinh")).as_ptr(), + Opcode::Cosh => NonNull::from(self.intrinsic(args, "cosh")).as_ptr(), + Opcode::Tanh => NonNull::from(self.intrinsic(args, "tanh")).as_ptr(), + Opcode::Asinh => NonNull::from(self.intrinsic(args, "asinh")).as_ptr(), + Opcode::Acosh => NonNull::from(self.intrinsic(args, "acosh")).as_ptr(), + Opcode::Atanh => NonNull::from(self.intrinsic(args, "atanh")).as_ptr(), + Opcode::Pow => NonNull::from(self.intrinsic(args, "llvm.pow.f64")).as_ptr(), + Opcode::OptBarrier => NonNull::from(self.values[args[0]].get(self)).as_ptr(), Opcode::Br | Opcode::Jmp | Opcode::Call | Opcode::Phi => unreachable!(), }; let res = self.func.dfg.first_result(inst); - self.values[res] = val.into(); + let val_ref: &'ll llvm_sys::LLVMValue = &*val; + self.values[res] = BuilderVal::Eager(val_ref); if matches!( opcode, @@ -695,61 +865,137 @@ impl<'ll> Builder<'_, '_, 'll> { | Opcode::Pow ) { match fast_math_mode { - FastMathMode::Full => llvm::LLVMSetFastMath(val), - FastMathMode::Partial => llvm::LLVMSetPartialFastMath(val), - FastMathMode::Disabled => (), + FastMathMode::Full => { + // Use all fast-math flags + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + unsafe { + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + } + } + FastMathMode::Partial => { + // Set specific fast-math flags + let fast_math_flags: c_uint = 0x01 | 0x02 | 0x10; // Reassoc | Reciprocal | Contract + unsafe { + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + } + } + FastMathMode::Disabled => (), // No fast-math flags } } } - unsafe fn strcmp(&mut self, args: &[Value], invert: bool) -> &'ll llvm::Value { + unsafe fn strcmp(&mut self, args: &[Value], invert: bool) -> &'ll llvm_sys::LLVMValue { let res = self.intrinsic(args, "strcmp"); - let predicate = if invert { llvm::IntPredicate::IntNE } else { llvm::IntPredicate::IntEQ }; + let predicate = if invert { + llvm_sys::LLVMIntPredicate::LLVMIntNE + } else { + llvm_sys::LLVMIntPredicate::LLVMIntEQ + }; - LLVMBuildICmp(self.llbuilder, predicate, res, self.cx.const_int(0), UNNAMED) + NonNull::new(llvm_sys::core::LLVMBuildICmp( + self.llbuilder, + predicate, + NonNull::from(res).as_ptr(), + NonNull::from(self.cx.const_int(0)).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn store(&self, ptr: &'ll llvm::Value, val: &'ll llvm::Value) { - LLVMBuildStore(self.llbuilder, val, ptr); + pub unsafe fn store(&self, ptr: &'ll llvm_sys::LLVMValue, val: &'ll llvm_sys::LLVMValue) { + llvm_sys::core::LLVMBuildStore( + self.llbuilder as *const _ as *mut _, + NonNull::from(val).as_ptr(), + NonNull::from(ptr).as_ptr(), + ); } /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn load(&self, ty: &'ll llvm::Type, ptr: &'ll llvm::Value) -> &'ll llvm::Value { - LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED) + pub unsafe fn load( + &self, + ty: &'ll llvm_sys::LLVMType, + ptr: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildLoad2( + self.llbuilder as *const _ as *mut _, + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } - /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn imul(&self, val1: &'ll llvm::Value, val2: &'ll llvm::Value) -> &'ll llvm::Value { - llvm::LLVMBuildMul(self.llbuilder, val1, val2, UNNAMED) + pub unsafe fn imul( + &self, + val1: &'ll llvm_sys::LLVMValue, + val2: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildMul( + self.llbuilder as *const _ as *mut _, + NonNull::from(val1).as_ptr(), + NonNull::from(val2).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn iadd(&self, val1: &'ll llvm::Value, val2: &'ll llvm::Value) -> &'ll llvm::Value { - llvm::LLVMBuildAdd(self.llbuilder, val1, val2, UNNAMED) + pub unsafe fn iadd( + &self, + val1: &'ll llvm_sys::LLVMValue, + val2: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildAdd( + self.llbuilder as *const _ as *mut _, + NonNull::from(val1).as_ptr(), + NonNull::from(val2).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety /// Must not be called when a block that already contains a terminator is selected pub unsafe fn ptr_diff( &self, - ty: &'ll llvm::Type, - ptr1: &'ll llvm::Value, - ptr2: &'ll llvm::Value, - ) -> &'ll llvm::Value { - llvm::LLVMBuildPtrDiff2(self.llbuilder, ty, ptr1, ptr2, UNNAMED) + ty: &'ll llvm_sys::LLVMType, + ptr1: &'ll llvm_sys::LLVMValue, + ptr2: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildPtrDiff2( + self.llbuilder as *const _ as *mut _, + NonNull::from(ty).as_ptr(), + NonNull::from(ptr1).as_ptr(), + NonNull::from(ptr2).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety /// /// Must not be called when a block that already contains a terminator is selected - pub unsafe fn is_null_ptr(&self, ptr: &'ll llvm::Value) -> &'ll llvm::Value { + pub unsafe fn is_null_ptr(&self, ptr: &'ll llvm_sys::LLVMValue) -> &'ll llvm_sys::LLVMValue { let null_ptr = self.cx.const_null_ptr(); - LLVMBuildICmp(self.llbuilder, llvm::IntPredicate::IntEQ, null_ptr, ptr, UNNAMED) + NonNull::new(llvm_sys::core::LLVMBuildICmp( + self.llbuilder as *const _ as *mut _, + llvm_sys::LLVMIntPredicate::LLVMIntEQ, + NonNull::from(null_ptr).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety @@ -757,8 +1003,8 @@ impl<'ll> Builder<'_, '_, 'll> { unsafe fn build_int_cmp( &mut self, args: &[Value], - predicate: llvm::IntPredicate, - ) -> &'ll llvm::Value { + predicate: llvm_sys::LLVMIntPredicate, + ) -> &'ll llvm_sys::LLVMValue { let lhs = self.values[args[0]].get(self); let rhs = self.values[args[1]].get(self); self.int_cmp(lhs, rhs, predicate) @@ -768,11 +1014,19 @@ impl<'ll> Builder<'_, '_, 'll> { /// Must not be called when a block that already contains a terminator is selected pub unsafe fn int_cmp( &self, - lhs: &'ll llvm::Value, - rhs: &'ll llvm::Value, - predicate: llvm::IntPredicate, - ) -> &'ll llvm::Value { - LLVMBuildICmp(self.llbuilder, predicate, lhs, rhs, UNNAMED) + lhs: &'ll llvm_sys::LLVMValue, + rhs: &'ll llvm_sys::LLVMValue, + predicate: llvm_sys::LLVMIntPredicate, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildICmp( + self.llbuilder as *const _ as *mut _, + predicate, + NonNull::from(lhs).as_ptr(), + NonNull::from(rhs).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } /// # Safety @@ -780,8 +1034,8 @@ impl<'ll> Builder<'_, '_, 'll> { unsafe fn build_real_cmp( &mut self, args: &[Value], - predicate: llvm::RealPredicate, - ) -> &'ll llvm::Value { + predicate: llvm_sys::LLVMRealPredicate, + ) -> &'ll llvm_sys::LLVMValue { let lhs = self.values[args[0]].get(self); let rhs = self.values[args[1]].get(self); self.real_cmp(lhs, rhs, predicate) @@ -791,18 +1045,34 @@ impl<'ll> Builder<'_, '_, 'll> { /// Must not be called when a block that already contains a terminator is selected pub unsafe fn real_cmp( &mut self, - lhs: &'ll llvm::Value, - rhs: &'ll llvm::Value, - predicate: llvm::RealPredicate, - ) -> &'ll llvm::Value { - llvm::LLVMBuildFCmp(self.llbuilder, predicate, lhs, rhs, UNNAMED) + lhs: &'ll llvm_sys::LLVMValue, + rhs: &'ll llvm_sys::LLVMValue, + predicate: llvm_sys::LLVMRealPredicate, + ) -> &'ll llvm_sys::LLVMValue { + NonNull::new(llvm_sys::core::LLVMBuildFCmp( + self.llbuilder, + predicate, + NonNull::from(lhs).as_ptr(), + NonNull::from(rhs).as_ptr(), + UNNAMED, + )) + .unwrap() + .as_ref() } - - unsafe fn intrinsic(&mut self, args: &[Value], name: &'static str) -> &'ll llvm::Value { + unsafe fn intrinsic(&mut self, args: &[Value], name: &'static str) -> &'ll llvm_sys::LLVMValue { let (ty, fun) = self.cx.intrinsic(name).unwrap_or_else(|| unreachable!("intrinsic {} not found", name)); let args: ArrayVec<_, 2> = args.iter().map(|arg| self.values[*arg].get(self)).collect(); - llvm::LLVMBuildCall2(self.llbuilder, ty, fun, args.as_ptr(), args.len() as u32, UNNAMED) + NonNull::new(llvm_sys::core::LLVMBuildCall2( + self.llbuilder, + NonNull::from(ty).as_ptr(), + NonNull::from(fun).as_ptr(), + args.as_ptr() as *mut _, + args.len() as u32, + UNNAMED, + )) + .unwrap() + .as_ref() } } diff --git a/openvaf/mir_llvm/src/callbacks.rs b/openvaf/mir_llvm/src/callbacks.rs index ecb3084..1e0f97e 100644 --- a/openvaf/mir_llvm/src/callbacks.rs +++ b/openvaf/mir_llvm/src/callbacks.rs @@ -1,69 +1,86 @@ -use llvm::UNNAMED; - -use crate::CodegenCx; +use crate::{CodegenCx, UNNAMED}; #[derive(Clone)] pub struct CallbackFun<'ll> { - pub fun_ty: &'ll llvm::Type, - pub fun: &'ll llvm::Value, + pub fun_ty: &'ll llvm_sys::LLVMType, + pub fun: &'ll llvm_sys::LLVMValue, /// Some Callbacks need to read/modify some state (typically passed as pointers) /// outside of the arguments provided in Verilog-A. /// These arguments are always passed before any arguments specified in the CFG - pub state: Box<[&'ll llvm::Value]>, + pub state: Box<[&'ll llvm_sys::LLVMValue]>, pub num_state: u32, } +use core::ptr::NonNull; impl<'ll> CodegenCx<'_, 'll> { pub fn const_callback( &self, - args: &[&'ll llvm::Type], - val: &'ll llvm::Value, + args: &[&'ll llvm_sys::LLVMType], + val: &'ll llvm_sys::LLVMValue, ) -> CallbackFun<'ll> { let name = self.local_callback_name(); + // println!("Creating const callback function: {}", name); // Logging the creation of the callback let fun_ty = self.ty_func(args, self.val_ty(val)); let fun = self.declare_int_fn(&name, fun_ty); unsafe { - let bb = llvm::LLVMAppendBasicBlockInContext(self.llcx, fun, UNNAMED); - let builder = llvm::LLVMCreateBuilderInContext(self.llcx); - llvm::LLVMPositionBuilderAtEnd(builder, bb); - llvm::LLVMBuildRet(builder, val); - llvm::LLVMDisposeBuilder(builder); + let bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let builder = + llvm_sys::core::LLVMCreateBuilderInContext(NonNull::from(self.llcx).as_ptr()); + llvm_sys::core::LLVMPositionBuilderAtEnd(builder, bb); + llvm_sys::core::LLVMBuildRet(builder, NonNull::from(val).as_ptr()); + llvm_sys::core::LLVMDisposeBuilder(builder); } CallbackFun { fun_ty, fun, state: Box::new([]), num_state: 0 } } - pub fn trivial_callbacks(&self, args: &[&'ll llvm::Type]) -> CallbackFun<'ll> { + pub fn trivial_callbacks(&self, args: &[&'ll llvm_sys::LLVMType]) -> CallbackFun<'ll> { let name = self.local_callback_name(); + //println!("Generating trivial callback with name: {}", name); // Log when trivial callback is generated. let fun_ty = self.ty_func(args, self.ty_void()); let fun = self.declare_int_fn(&name, fun_ty); unsafe { - let bb = llvm::LLVMAppendBasicBlockInContext(self.llcx, fun, UNNAMED); - let builder = llvm::LLVMCreateBuilderInContext(self.llcx); - llvm::LLVMPositionBuilderAtEnd(builder, bb); - llvm::LLVMBuildRetVoid(builder); - llvm::LLVMDisposeBuilder(builder); + let bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let builder = + llvm_sys::core::LLVMCreateBuilderInContext(NonNull::from(self.llcx).as_ptr()); + llvm_sys::core::LLVMPositionBuilderAtEnd(builder, bb); + llvm_sys::core::LLVMBuildRetVoid(builder); + llvm_sys::core::LLVMDisposeBuilder(builder); } CallbackFun { fun_ty, fun, state: Box::new([]), num_state: 0 } } - pub fn const_return(&self, args: &[&'ll llvm::Type], idx: usize) -> CallbackFun<'ll> { + pub fn const_return(&self, args: &[&'ll llvm_sys::LLVMType], idx: usize) -> CallbackFun<'ll> { let name = self.local_callback_name(); let fun_ty = self.ty_func(args, args[idx]); let fun = self.declare_int_fn(&name, fun_ty); unsafe { - let bb = llvm::LLVMAppendBasicBlockInContext(self.llcx, fun, UNNAMED); - let builder = llvm::LLVMCreateBuilderInContext(self.llcx); - llvm::LLVMPositionBuilderAtEnd(builder, bb); - let val = llvm::LLVMGetParam(fun, idx as u32); - llvm::LLVMBuildRet(builder, val); - llvm::LLVMDisposeBuilder(builder); + let bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(self.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let builder = + llvm_sys::core::LLVMCreateBuilderInContext(NonNull::from(self.llcx).as_ptr()); + llvm_sys::core::LLVMPositionBuilderAtEnd(builder, bb); + let val = llvm_sys::core::LLVMGetParam(NonNull::from(fun).as_ptr(), idx as u32); + llvm_sys::core::LLVMBuildRet(builder, val); + llvm_sys::core::LLVMDisposeBuilder(builder); } CallbackFun { fun_ty, fun, state: Box::new([]), num_state: 0 } } pub fn local_callback_name(&self) -> String { - self.generate_local_symbol_name("cb") + let name = self.generate_local_symbol_name("cb"); + name } } diff --git a/openvaf/mir_llvm/src/context.rs b/openvaf/mir_llvm/src/context.rs index cf4f71f..303e8b0 100644 --- a/openvaf/mir_llvm/src/context.rs +++ b/openvaf/mir_llvm/src/context.rs @@ -1,21 +1,23 @@ use std::cell::{Cell, RefCell}; use std::ffi::CString; +use std::ptr::NonNull; use ahash::AHashMap; use lasso::{Rodeo, Spur}; use libc::{c_char, c_uint}; -use llvm::support::LLVMString; -use llvm::{ - LLVMCreateMemoryBufferWithMemoryRange, LLVMGetNamedFunction, LLVMLinkModules2, - LLVMParseBitcodeInContext2, Type, Value, -}; +use llvm_sys::bit_reader::LLVMParseBitcodeInContext2; +//use llvm_sys::LLVMBool; // For False, if applicable +use llvm_sys::core::{LLVMCreateMemoryBufferWithMemoryRange, LLVMGetNamedFunction}; +use llvm_sys::linker::LLVMLinkModules2; +use llvm_sys::{LLVMType as Type, LLVMValue as Value}; use target::spec::Target; use crate::types::Types; +use crate::LLVMString; pub struct CodegenCx<'a, 'll> { - pub llmod: &'ll llvm::Module, - pub llcx: &'ll llvm::Context, + pub llmod: &'ll llvm_sys::LLVMModule, + pub llcx: &'ll llvm_sys::LLVMContext, pub target: &'a Target, // pub target_cpu: &'a str, @@ -34,23 +36,30 @@ impl<'a, 'll> CodegenCx<'a, 'll> { // target_cpu: &'a str, ) -> CodegenCx<'a, 'll> { // let ty_isize = - // unsafe { llvm::LLVMIntTypeInContext(llvm_module.llcx, target.pointer_width) }; + // unsafe { llvm_sys::core::LLVMIntTypeInContext(llvm_module.llcx, target.pointer_width) }; CodegenCx { llmod: llvm_module.llmod(), - llcx: llvm_module.llcx, + llcx: unsafe { &*llvm_module.llcx }, str_lit_cache: RefCell::new(AHashMap::with_capacity(literals.len())), literals, intrinsics: RefCell::new(AHashMap::new()), local_gen_sym_counter: Cell::new(0), // target_cpu, target, - tys: Types::new(llvm_module.llcx, target.pointer_width), + tys: Types::new(unsafe { &*llvm_module.llcx }, target.pointer_width), } } - pub fn get_func_by_name(&self, name: &str) -> Option<&'ll llvm::Value> { + pub fn get_func_by_name(&self, name: &str) -> Option<&'ll Value> { let name = CString::new(name).unwrap(); - unsafe { LLVMGetNamedFunction(self.llmod, name.as_ptr()) } + unsafe { + let ptr = LLVMGetNamedFunction(NonNull::from(self.llmod).as_ptr(), name.as_ptr()); + if ptr.is_null() { + None + } else { + Some(&*(ptr as *const Value)) + } + } } pub fn include_bitcode(&self, bitcode: &[u8]) { @@ -61,22 +70,27 @@ impl<'a, 'll> CodegenCx<'a, 'll> { bitcode.as_ptr() as *const c_char, bitcode.len(), sym.as_ptr(), - llvm::False, + 0, ); - let mut module = None; + let mut module: *mut llvm_sys::LLVMModule = std::ptr::null_mut(); assert!( - LLVMParseBitcodeInContext2(self.llcx, buff, &mut module) == llvm::False, + LLVMParseBitcodeInContext2(NonNull::from(self.llcx).as_ptr(), buff, &mut module) + == 0, "failed to parse bitcode" ); + assert!(!module.is_null(), "parsed module is null"); assert!( - LLVMLinkModules2(self.llmod, module.unwrap()) == llvm::False, + LLVMLinkModules2(NonNull::from(self.llmod).as_ptr(), module) == 0, "failed to link parsed bitcode" ); } } - pub fn to_str(&self) -> LLVMString { - unsafe { LLVMString::new(llvm::LLVMPrintModuleToString(self.llmod)) } + unsafe { + LLVMString::new(llvm_sys::core::LLVMPrintModuleToString( + NonNull::from(self.llmod).as_ptr(), + )) + } } pub fn const_str_uninterned(&self, lit: &str) -> &'ll Value { @@ -94,23 +108,26 @@ impl<'a, 'll> CodegenCx<'a, 'll> { // assert!(!val.contains(&b'\0')); // val.push(b'\0'); let val = unsafe { - llvm::LLVMConstStringInContext( - self.llcx, + llvm_sys::core::LLVMConstStringInContext( + NonNull::from(self.llcx).as_ptr(), val.as_ptr() as *const c_char, val.len() as c_uint, - false as llvm::Bool, + 0, ) }; let sym = self.generate_local_symbol_name("str"); - let ty = self.val_ty(val); + let ty = self.val_ty(unsafe { &*val }); let global = self .define_global(&sym, ty) .unwrap_or_else(|| unreachable!("symbol {} already defined", sym)); unsafe { - llvm::LLVMSetInitializer(global, val); - llvm::LLVMSetGlobalConstant(global, llvm::True); - llvm::LLVMSetLinkage(global, llvm::Linkage::Internal); + llvm_sys::core::LLVMSetInitializer(NonNull::from(global).as_ptr(), val); + llvm_sys::core::LLVMSetGlobalConstant(NonNull::from(global).as_ptr(), 1); + llvm_sys::core::LLVMSetLinkage( + NonNull::from(global).as_ptr(), + llvm_sys::LLVMLinkage::LLVMInternalLinkage, + ); } self.str_lit_cache.borrow_mut().insert(lit, global); global diff --git a/openvaf/mir_llvm/src/declarations.rs b/openvaf/mir_llvm/src/declarations.rs index 76ff9c3..cbf3f6b 100644 --- a/openvaf/mir_llvm/src/declarations.rs +++ b/openvaf/mir_llvm/src/declarations.rs @@ -1,10 +1,15 @@ use std::ffi::CString; -use libc::c_char; -use llvm::{False, LLVMTypeOf, Type, Value}; +use libc::{c_char, c_uint}; +use llvm_sys::core::LLVMTypeOf; +use llvm_sys::prelude::LLVMBool; +use llvm_sys::{LLVMType as Type, LLVMValue as Value}; -use crate::CodegenCx; +const FALSE: LLVMBool = 0; + +use std::ptr::NonNull; +use crate::CodegenCx; /// Declare a function. /// /// If there’s a value with the same name already declared, the function will @@ -12,17 +17,21 @@ use crate::CodegenCx; pub fn declare_raw_fn<'ll>( cx: &CodegenCx<'_, 'll>, name: &str, - callconv: llvm::CallConv, - unnamed: llvm::UnnamedAddr, + callconv: llvm_sys::LLVMCallConv, + unnamed: llvm_sys::LLVMUnnamedAddr, ty: &'ll Type, ) -> &'ll Value { let name = CString::new(name).unwrap(); unsafe { - let llfn = llvm::LLVMAddFunction(cx.llmod, name.as_ptr() as *const c_char, ty); + let llfn = llvm_sys::core::LLVMAddFunction( + NonNull::from(cx.llmod).as_ptr(), + name.as_ptr() as *const c_char, + NonNull::from(ty).as_ptr(), + ); - llvm::LLVMSetFunctionCallConv(llfn, callconv); - llvm::LLVMSetUnnamedAddress(llfn, unnamed); - llfn + llvm_sys::core::LLVMSetFunctionCallConv(llfn, callconv as c_uint); + llvm_sys::core::LLVMSetUnnamedAddress(llfn, unnamed); + &*llfn } } @@ -41,10 +50,16 @@ impl<'a, 'll> CodegenCx<'a, 'll> { pub fn declare_ext_fn( &self, name: &str, - // unnamed: llvm::UnnamedAddr, + // unnamed: llvm_sys::LLVMUnnamedAddr, fn_type: &'ll Type, ) -> &'ll Value { - declare_raw_fn(self, name, llvm::CallConv::CCallConv, llvm::UnnamedAddr::No, fn_type) + declare_raw_fn( + self, + name, + llvm_sys::LLVMCallConv::LLVMCCallConv, + llvm_sys::LLVMUnnamedAddr::LLVMNoUnnamedAddr, + fn_type, + ) } /// Declare a internal function. @@ -53,11 +68,16 @@ impl<'a, 'll> CodegenCx<'a, 'll> { let fun = declare_raw_fn( self, name, - llvm::CallConv::FastCallConv, - llvm::UnnamedAddr::Global, + llvm_sys::LLVMCallConv::LLVMFastCallConv, + llvm_sys::LLVMUnnamedAddr::LLVMGlobalUnnamedAddr, fn_type, ); - unsafe { llvm::LLVMSetLinkage(fun, llvm::Linkage::Internal) } + unsafe { + llvm_sys::core::LLVMSetLinkage( + NonNull::from(fun).as_ptr(), + llvm_sys::LLVMLinkage::LLVMInternalLinkage, + ) + } fun } @@ -67,11 +87,16 @@ impl<'a, 'll> CodegenCx<'a, 'll> { let fun = declare_raw_fn( self, name, - llvm::CallConv::CCallConv, - llvm::UnnamedAddr::Global, + llvm_sys::LLVMCallConv::LLVMCCallConv, + llvm_sys::LLVMUnnamedAddr::LLVMGlobalUnnamedAddr, fn_type, ); - unsafe { llvm::LLVMSetLinkage(fun, llvm::Linkage::Internal) } + unsafe { + llvm_sys::core::LLVMSetLinkage( + NonNull::from(fun).as_ptr(), + llvm_sys::LLVMLinkage::LLVMInternalLinkage, + ) + } fun } @@ -84,8 +109,14 @@ impl<'a, 'll> CodegenCx<'a, 'll> { None } else { let name = CString::new(name).unwrap(); - let global = unsafe { llvm::LLVMAddGlobal(self.llmod, ty, name.as_ptr()) }; - Some(global) + let global = unsafe { + llvm_sys::core::LLVMAddGlobal( + NonNull::from(self.llmod).as_ptr(), + NonNull::from(ty).as_ptr(), + name.as_ptr(), + ) + }; + Some(unsafe { &*global }) } } @@ -94,23 +125,33 @@ impl<'a, 'll> CodegenCx<'a, 'll> { /// Use this function when you intend to define a global without a name. pub fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { unsafe { - let global = llvm::LLVMAddGlobal(self.llmod, ty, llvm::UNNAMED); - llvm::LLVMSetLinkage(global, llvm::Linkage::PrivateLinkage); - global + let global = llvm_sys::core::LLVMAddGlobal( + NonNull::from(self.llmod).as_ptr(), + NonNull::from(ty).as_ptr(), + crate::UNNAMED, + ); + llvm_sys::core::LLVMSetLinkage(global, llvm_sys::LLVMLinkage::LLVMPrivateLinkage); + &*global } } /// Gets declared value by name. pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { let name = CString::new(name).unwrap(); - unsafe { llvm::LLVMGetNamedGlobal(self.llmod, name.as_ptr()) } + unsafe { + Some(&*llvm_sys::core::LLVMGetNamedGlobal( + NonNull::from(self.llmod).as_ptr(), + name.as_ptr(), + )) + } } /// Gets defined or externally defined (AvailableExternally linkage) value by /// name. pub fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { self.get_declared_value(name).and_then(|val| { - let declaration = unsafe { llvm::LLVMIsDeclaration(val) != False }; + let declaration = + unsafe { llvm_sys::core::LLVMIsDeclaration(NonNull::from(val).as_ptr()) != FALSE }; if !declaration { Some(val) } else { @@ -127,37 +168,48 @@ impl<'a, 'll> CodegenCx<'a, 'll> { is_const: bool, ) -> &'ll Value { unsafe { - let res = self + let rest = self .define_global(name, ty) .unwrap_or_else(|| unreachable!("symbol '{}' already defined", name)); + let res = NonNull::from(rest).as_ptr(); - llvm::LLVMSetInitializer(res, val); - llvm::LLVMSetLinkage(res, llvm::Linkage::ExternalLinkage); - llvm::LLVMSetUnnamedAddress(res, llvm::UnnamedAddr::No); - llvm::LLVMSetDLLStorageClass(res, llvm::DLLStorageClass::Export); + llvm_sys::core::LLVMSetInitializer(res, NonNull::from(val).as_ptr()); + llvm_sys::core::LLVMSetLinkage(res, llvm_sys::LLVMLinkage::LLVMExternalLinkage); + llvm_sys::core::LLVMSetUnnamedAddress( + res, + llvm_sys::LLVMUnnamedAddr::LLVMNoUnnamedAddr, + ); + llvm_sys::core::LLVMSetDLLStorageClass( + res, + llvm_sys::LLVMDLLStorageClass::LLVMDLLExportStorageClass, + ); if is_const { - llvm::LLVMSetGlobalConstant(res, llvm::True); + llvm_sys::core::LLVMSetGlobalConstant(res, 1); } - res + rest } } pub fn global_const(&self, ty: &'ll Type, val: &'ll Value) -> &'ll Value { unsafe { - let res = self.define_private_global(ty); - llvm::LLVMSetInitializer(res, val); - llvm::LLVMSetUnnamedAddress(res, llvm::UnnamedAddr::No); - llvm::LLVMSetGlobalConstant(res, llvm::True); - res + let rest = self.define_private_global(ty); + let res = NonNull::from(rest).as_ptr(); + llvm_sys::core::LLVMSetInitializer(res, NonNull::from(val).as_ptr()); + llvm_sys::core::LLVMSetUnnamedAddress( + res, + llvm_sys::LLVMUnnamedAddr::LLVMNoUnnamedAddr, + ); + llvm_sys::core::LLVMSetGlobalConstant(res, 1); + rest } } pub fn const_arr_ptr(&self, elem_ty: &'ll Type, vals: &[&'ll Value]) -> &'ll Value { for (i, val) in vals.iter().enumerate() { assert_eq!( - unsafe { LLVMTypeOf(val) } as *const Type, + unsafe { LLVMTypeOf(NonNull::from(*val).as_ptr()) } as *const Type, elem_ty as *const Type, "val {i} not eq" ) @@ -172,9 +224,15 @@ impl<'a, 'll> CodegenCx<'a, 'll> { .unwrap_or_else(|| unreachable!("symbol {} already defined", sym)); unsafe { - llvm::LLVMSetInitializer(global, val); - llvm::LLVMSetGlobalConstant(global, llvm::True); - llvm::LLVMSetLinkage(global, llvm::Linkage::Internal); + llvm_sys::core::LLVMSetInitializer( + NonNull::from(global).as_ptr(), + NonNull::from(val).as_ptr(), + ); + llvm_sys::core::LLVMSetGlobalConstant(NonNull::from(global).as_ptr(), 1); + llvm_sys::core::LLVMSetLinkage( + NonNull::from(global).as_ptr(), + llvm_sys::LLVMLinkage::LLVMInternalLinkage, + ); } global } @@ -215,22 +273,27 @@ impl<'a, 'll> CodegenCx<'a, 'll> { .unwrap_or_else(|| unreachable!("symbol '{}' already defined", name)); unsafe { - let init = llvm::LLVMConstNull(ty); - llvm::LLVMSetInitializer(arr, init); - llvm::LLVMSetLinkage(arr, llvm::Linkage::ExternalLinkage); + let init = llvm_sys::core::LLVMConstNull(NonNull::from(ty).as_ptr()); + llvm_sys::core::LLVMSetInitializer(NonNull::from(arr).as_ptr(), init); + llvm_sys::core::LLVMSetLinkage( + NonNull::from(arr).as_ptr(), + llvm_sys::LLVMLinkage::LLVMExternalLinkage, + ); } if add_cnt { let name = format!("{}.cnt", name); - let arr_len = self - .define_global(&name, self.ty_size()) - .unwrap_or_else(|| unreachable!("symbol '{}' already defined", name)); + let arr_len = NonNull::from( + self.define_global(&name, self.ty_size()) + .unwrap_or_else(|| unreachable!("symbol '{}' already defined", name)), + ) + .as_ptr(); unsafe { let init = self.const_usize(len); - llvm::LLVMSetInitializer(arr_len, init); - llvm::LLVMSetGlobalConstant(arr_len, llvm::True); - llvm::LLVMSetLinkage(arr_len, llvm::Linkage::ExternalLinkage); + llvm_sys::core::LLVMSetInitializer(arr_len, NonNull::from(init).as_ptr()); + llvm_sys::core::LLVMSetGlobalConstant(arr_len, 1); + llvm_sys::core::LLVMSetLinkage(arr_len, llvm_sys::LLVMLinkage::LLVMExternalLinkage); } } diff --git a/openvaf/mir_llvm/src/intrinsics.rs b/openvaf/mir_llvm/src/intrinsics.rs index 825e1a5..d5cc92b 100644 --- a/openvaf/mir_llvm/src/intrinsics.rs +++ b/openvaf/mir_llvm/src/intrinsics.rs @@ -1,4 +1,4 @@ -use llvm::{Type, Value}; +use llvm_sys::{LLVMType as Type, LLVMValue as Value}; use crate::CodegenCx; @@ -92,10 +92,10 @@ impl<'a, 'll> CodegenCx<'a, 'll> { fn insert_intrinsic( &self, name: &'static str, - args: &[&'ll llvm::Type], - ret: &'ll llvm::Type, + args: &[&'ll Type], + ret: &'ll Type, variadic: bool, - ) -> (&'ll llvm::Type, &'ll llvm::Value) { + ) -> (&'ll Type, &'ll Value) { let fn_ty = if variadic { self.ty_variadic_func(&[], ret) } else { self.ty_func(args, ret) }; let f = self.get_func_by_name(name).unwrap_or_else(|| self.declare_ext_fn(name, fn_ty)); diff --git a/openvaf/mir_llvm/src/lib.rs b/openvaf/mir_llvm/src/lib.rs index c8b3fdd..68067a3 100644 --- a/openvaf/mir_llvm/src/lib.rs +++ b/openvaf/mir_llvm/src/lib.rs @@ -1,17 +1,88 @@ +use std::error::Error; use std::ffi::{CStr, CString}; +use std::fmt::{self, Debug, Display, Formatter}; use std::mem::MaybeUninit; -use std::os::raw::c_char; +use std::ops::Deref; +use std::os::raw::{c_char, c_uint, c_ulonglong}; use std::path::Path; use std::ptr; +use std::ptr::NonNull; use lasso::Rodeo; use libc::c_void; -use llvm::support::LLVMString; -pub use llvm::OptLevel; -use llvm::{ - LLVMDisposeMessage, LLVMGetDiagInfoDescription, LLVMGetDiagInfoSeverity, - LLVMGetHostCPUFeatures, LLVMGetHostCPUName, LLVMPassManagerBuilderDispose, -}; +use llvm_sys::core; +use llvm_sys::core::{LLVMCreateMessage, LLVMDisposeMessage}; +use llvm_sys::error::LLVMGetErrorMessage; +use llvm_sys::transforms::pass_builder::*; + +pub const UNNAMED: *const c_char = b"\0".as_ptr() as *const c_char; +#[derive(Eq)] +#[repr(transparent)] +pub struct LLVMString { + ptr: *const c_char, +} + +impl LLVMString { + pub unsafe fn new(ptr: *const c_char) -> Self { + LLVMString { ptr } + } + + pub(crate) fn create_from_str(string: &str) -> LLVMString { + let msg = CString::new(string).unwrap(); + unsafe { LLVMString::new(LLVMCreateMessage(msg.as_ptr())) } + } + + pub fn create_from_c_str(string: &CStr) -> LLVMString { + unsafe { LLVMString::new(LLVMCreateMessage(string.as_ptr())) } + } +} + +impl Deref for LLVMString { + type Target = CStr; + + fn deref(&self) -> &Self::Target { + unsafe { CStr::from_ptr(self.ptr) } + } +} + +impl Debug for LLVMString { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{:?}", self.deref()) + } +} + +impl Display for LLVMString { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", self.deref().to_string_lossy()) + } +} + +impl PartialEq for LLVMString { + fn eq(&self, other: &LLVMString) -> bool { + **self == **other + } +} + +impl Error for LLVMString { + fn description(&self) -> &str { + self.to_str().expect("Could not convert LLVMString to str (likely invalid unicode)") + } + + fn cause(&self) -> Option<&dyn Error> { + None + } +} + +impl Drop for LLVMString { + fn drop(&mut self) { + unsafe { + LLVMDisposeMessage(self.ptr as *mut _); + } + } +} + +use llvm_sys::core::{LLVMGetDiagInfoDescription, LLVMGetDiagInfoSeverity}; +use llvm_sys::target_machine::{LLVMCodeGenOptLevel, LLVMGetHostCPUFeatures, LLVMGetHostCPUName}; use target::spec::Target; mod builder; @@ -27,7 +98,6 @@ mod tests; pub use builder::{Builder, BuilderVal, MemLoc}; pub use callbacks::CallbackFun; pub use context::CodegenCx; - pub struct LLVMBackend<'t> { target: &'t Target, target_cpu: String, @@ -36,7 +106,7 @@ pub struct LLVMBackend<'t> { impl<'t> LLVMBackend<'t> { pub fn new( - cg_opts: &[String], + _cg_opts: &[String], target: &'t Target, mut target_cpu: String, target_features: &[String], @@ -94,7 +164,9 @@ impl<'t> LLVMBackend<'t> { features.extend(target_features.iter().cloned()); // TODO add target options here if we ever have any - llvm::initialization::init(cg_opts, &[]); + // https://reviews.llvm.org/D145043 + //llvm_sys::initialization::init(cg_opts, &[]); + //https://github.com/llvm/llvm-project/commit/62ef97e0631ff41ad53436477cecc7d3eb244d1b LLVMBackend { target, target_cpu, features: features.join(",") } } @@ -105,7 +177,7 @@ impl<'t> LLVMBackend<'t> { pub unsafe fn new_module( &self, name: &str, - opt_lvl: OptLevel, + opt_lvl: LLVMCodeGenOptLevel, ) -> Result { ModuleLlvm::new(name, self.target, &self.target_cpu, &self.features, opt_lvl) } @@ -121,6 +193,7 @@ impl<'t> LLVMBackend<'t> { ) -> CodegenCx<'a, 'll> { CodegenCx::new(literals, module, self.target) } + pub fn target(&self) -> &'t Target { self.target } @@ -130,85 +203,253 @@ impl Drop for LLVMBackend<'_> { fn drop(&mut self) {} } -extern "C" fn diagnostic_handler(info: &llvm::DiagnosticInfo, _: *mut c_void) { - let severity = unsafe { LLVMGetDiagInfoSeverity(info) }; - let msg = unsafe { LLVMString::new(LLVMGetDiagInfoDescription(info)) }; - match severity { - llvm::DiagnosticSeverity::Error => log::error!("{msg}"), - llvm::DiagnosticSeverity::Warning => log::warn!("{msg}"), - llvm::DiagnosticSeverity::Remark => log::debug!("{msg}"), - llvm::DiagnosticSeverity::Note => log::trace!("{msg}"), +extern "C" fn diagnostic_handler(info: *mut llvm_sys::LLVMDiagnosticInfo, _: *mut c_void) { + unsafe { + let severity = LLVMGetDiagInfoSeverity(info); + let msg = LLVMString::new(LLVMGetDiagInfoDescription(info)); + match severity { + llvm_sys::LLVMDiagnosticSeverity::LLVMDSError => log::error!("{msg}"), + llvm_sys::LLVMDiagnosticSeverity::LLVMDSWarning => log::warn!("{msg}"), + llvm_sys::LLVMDiagnosticSeverity::LLVMDSRemark => log::debug!("{msg}"), + llvm_sys::LLVMDiagnosticSeverity::LLVMDSNote => log::trace!("{msg}"), + } + } +} + +// Helper function to convert Rust string to C string +fn to_c_string(s: &str) -> CString { + CString::new(s).unwrap() +} + +// Helper function to convert C string to Rust string +unsafe fn from_c_string(s: *const c_char) -> String { + CStr::from_ptr(s).to_string_lossy().into_owned() +} + +/// # Safety +/// +/// This function calls the LLVM C interface and may emit unsafety for invalid inputs. +/// Specifically this function is not thread save! +pub unsafe fn create_target( + triple: &str, + cpu: &str, + features: &str, + level: llvm_sys::target_machine::LLVMCodeGenOptLevel, + reloc_mode: llvm_sys::target_machine::LLVMRelocMode, + code_model: llvm_sys::target_machine::LLVMCodeModel, +) -> Result { + let triple_ = LLVMString::create_from_c_str(&CString::new(triple).unwrap()); + let triple_ = + LLVMString::new(llvm_sys::target_machine::LLVMNormalizeTargetTriple(triple_.as_ptr())); + let mut target: llvm_sys::target_machine::LLVMTargetRef = std::ptr::null_mut(); + let mut err_string = MaybeUninit::uninit(); + + let code = llvm_sys::target_machine::LLVMGetTargetFromTriple( + triple_.as_ptr(), + &mut target, + err_string.as_mut_ptr(), + ); + + if code == 1 { + return Err(LLVMString::new(err_string.assume_init())); + } + + let cpu = LLVMString::create_from_str(cpu); + let features = CString::new(features).unwrap(); + + let target_machine = llvm_sys::target_machine::LLVMCreateTargetMachine( + target, + triple_.as_ptr(), + cpu.as_ptr(), + features.as_ptr(), + level, + reloc_mode, + code_model, + ); + + if target_machine.is_null() { + return Err(LLVMString::create_from_c_str( + CStr::from_bytes_with_nul( + format!("error: code gen not available for target \"{}\"\0", triple).as_bytes(), + ) + .unwrap(), + )); + } + + Ok(target_machine) +} + +pub unsafe fn set_normalized_target(module: llvm_sys::prelude::LLVMModuleRef, triple: &str) { + let triple_c = to_c_string(triple); + let normalized_triple = llvm_sys::target_machine::LLVMNormalizeTargetTriple(triple_c.as_ptr()); + llvm_sys::core::LLVMSetTarget(module, normalized_triple); + llvm_sys::core::LLVMDisposeMessage(normalized_triple); +} + +pub unsafe fn get_host_cpu_name() -> String { + from_c_string(llvm_sys::target_machine::LLVMGetHostCPUName()) +} + +pub unsafe fn get_host_cpu_features() -> String { + from_c_string(llvm_sys::target_machine::LLVMGetHostCPUFeatures()) +} + +pub unsafe fn offset_of_element( + td: llvm_sys::target::LLVMTargetDataRef, + struct_ty: llvm_sys::prelude::LLVMTypeRef, + elem: c_uint, +) -> c_ulonglong { + llvm_sys::target::LLVMOffsetOfElement(td, struct_ty, elem) +} + +pub unsafe fn create_target_data(string_rep: &str) -> llvm_sys::target::LLVMTargetDataRef { + let string_rep_c = to_c_string(string_rep); + llvm_sys::target::LLVMCreateTargetData(string_rep_c.as_ptr()) +} + +pub unsafe fn dispose_target_data(target_data: llvm_sys::target::LLVMTargetDataRef) { + llvm_sys::target::LLVMDisposeTargetData(target_data); +} + +pub unsafe fn abi_size_of_type( + data: llvm_sys::target::LLVMTargetDataRef, + ty: llvm_sys::prelude::LLVMTypeRef, +) -> c_ulonglong { + llvm_sys::target::LLVMABISizeOfType(data, ty) +} + +pub unsafe fn abi_alignment_of_type( + data: llvm_sys::target::LLVMTargetDataRef, + ty: llvm_sys::prelude::LLVMTypeRef, +) -> c_uint { + llvm_sys::target::LLVMABIAlignmentOfType(data, ty) +} + +pub unsafe fn target_machine_emit_to_file( + target: llvm_sys::target_machine::LLVMTargetMachineRef, + module: llvm_sys::prelude::LLVMModuleRef, + filename: &str, + codegen: llvm_sys::target_machine::LLVMCodeGenFileType, +) -> Result<(), String> { + let filename_c = to_c_string(filename); + let mut error_msg: *mut c_char = ptr::null_mut(); + + if llvm_sys::target_machine::LLVMTargetMachineEmitToFile( + target, + module, + filename_c.as_ptr(), + codegen, + &mut error_msg, + ) != 0 + { + let error = from_c_string(error_msg); + llvm_sys::core::LLVMDisposeMessage(error_msg); + Err(error) + } else { + Ok(()) } } pub struct ModuleLlvm { - llcx: &'static mut llvm::Context, - // must be a raw pointer because the reference must not outlife self/the context - llmod_raw: *const llvm::Module, - tm: &'static mut llvm::TargetMachine, - opt_lvl: OptLevel, + llcx: llvm_sys::prelude::LLVMContextRef, + llmod_raw: llvm_sys::prelude::LLVMModuleRef, + tm: llvm_sys::target_machine::LLVMTargetMachineRef, + opt_lvl: llvm_sys::target_machine::LLVMCodeGenOptLevel, } impl ModuleLlvm { - unsafe fn new( + pub unsafe fn new( name: &str, target: &Target, target_cpu: &str, features: &str, - opt_lvl: OptLevel, + opt_lvl: llvm_sys::target_machine::LLVMCodeGenOptLevel, ) -> Result { - let llcx = llvm::LLVMContextCreate(); + let llcx = llvm_sys::core::LLVMContextCreate(); let target_data_layout = target.data_layout.clone(); - llvm::LLVMContextSetDiagnosticHandler(llcx, Some(diagnostic_handler), ptr::null_mut()); + llvm_sys::core::LLVMContextSetDiagnosticHandler( + llcx, + Some(diagnostic_handler), + ptr::null_mut(), + ); let name = CString::new(name).unwrap(); - let llmod = llvm::LLVMModuleCreateWithNameInContext(name.as_ptr(), llcx); + let llmod = llvm_sys::core::LLVMModuleCreateWithNameInContext(name.as_ptr(), llcx); let data_layout = CString::new(&*target_data_layout).unwrap(); - llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); - llvm::set_normalized_target(llmod, &target.llvm_target); + llvm_sys::core::LLVMSetDataLayout(llmod, data_layout.as_ptr()); - let tm = llvm::create_target( + set_normalized_target(llmod, &target.llvm_target); + + let tm = create_target( &target.llvm_target, target_cpu, features, opt_lvl, - llvm::RelocMode::PIC, - llvm::CodeModel::Default, + llvm_sys::target_machine::LLVMRelocMode::LLVMRelocPIC, + llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelDefault, )?; - let llmod_raw = llmod as _; - Ok(ModuleLlvm { llcx, llmod_raw, tm, opt_lvl }) + Ok(ModuleLlvm { llcx, llmod_raw: llmod, tm, opt_lvl }) } pub fn to_str(&self) -> LLVMString { - unsafe { LLVMString::new(llvm::LLVMPrintModuleToString(self.llmod())) } + unsafe { + LLVMString::new(llvm_sys::core::LLVMPrintModuleToString( + NonNull::from(self.llmod()).as_ptr(), + )) + } } - pub fn llmod(&self) -> &llvm::Module { + pub fn llmod(&self) -> &llvm_sys::LLVMModule { unsafe { &*self.llmod_raw } } - pub fn optimize(&self) { let llmod = self.llmod(); unsafe { - let builder = llvm::LLVMPassManagerBuilderCreate(); - llvm::pass_manager_builder_set_opt_lvl(builder, self.opt_lvl); - llvm::LLVMPassManagerBuilderSetSizeLevel(builder, 0); + // Create PassBuilderOptions + let options = LLVMCreatePassBuilderOptions(); //this is opaque LLVMPassBuilderOptionsRef + + // Set optimization level + let opt_level = match self.opt_lvl { + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone => { + "default" + } + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelLess => { + "default" + } + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault => { + "default" + } + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive => { + "default" + } + }; - let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod); - llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(builder, fpm); - llvm::run_function_pass_manager(fpm, llmod); - llvm::LLVMDisposePassManager(fpm); + let error = { + // Create variables in inner scope + let opt_level_cstring = CString::new(opt_level).unwrap(); + let opt_level_ptr = opt_level_cstring.as_ptr(); - let mpm = llvm::LLVMCreatePassManager(); - llvm::LLVMPassManagerBuilderPopulateModulePassManager(builder, mpm); - llvm::LLVMRunPassManager(mpm, llmod); - llvm::LLVMDisposePassManager(mpm); + let llmod_ptr = NonNull::from(llmod).as_ptr(); - LLVMPassManagerBuilderDispose(builder); + // Run passes while values are guaranteed to be alive + LLVMRunPasses(llmod_ptr, opt_level_ptr, self.tm, options) + }; + // Check for errors + if !error.is_null() { + // Handle error + let error_string = LLVMGetErrorMessage(error); + let rust_str = + std::ffi::CStr::from_ptr(error_string).to_string_lossy().into_owned(); + eprintln!("Error occurred during optimization: {}", rust_str); + core::LLVMDisposeMessage(error_string); + } + + // Clean up + LLVMDisposePassBuilderOptions(options); } } @@ -218,8 +459,11 @@ impl ModuleLlvm { /// Whether this module is valid (true if valid) pub fn verify_and_print(&self) -> bool { unsafe { - llvm::LLVMVerifyModule(self.llmod(), llvm::VerifierFailureAction::PrintMessage, None) - == llvm::False + llvm_sys::analysis::LLVMVerifyModule( + self.llmod_raw, // Use the raw pointer directly + llvm_sys::analysis::LLVMVerifierFailureAction::LLVMPrintMessageAction, + std::ptr::null_mut(), // Use null pointer instead of None + ) == 0 } } @@ -229,14 +473,20 @@ impl ModuleLlvm { /// An error messages in case the module invalid pub fn verify(&self) -> Option { unsafe { - let mut res = MaybeUninit::uninit(); - if llvm::LLVMVerifyModule( - self.llmod(), - llvm::VerifierFailureAction::ReturnStatus, - Some(&mut res), - ) == llvm::True + let mut out_message: *mut i8 = std::ptr::null_mut(); + if llvm_sys::analysis::LLVMVerifyModule( + self.llmod_raw, + llvm_sys::analysis::LLVMVerifierFailureAction::LLVMReturnStatusAction, + &mut out_message, + ) == 1 { - Some(res.assume_init()) + if !out_message.is_null() { + let message = LLVMString::new(out_message); + llvm_sys::core::LLVMDisposeMessage(out_message); + Some(message) + } else { + None + } } else { None } @@ -250,11 +500,11 @@ impl ModuleLlvm { let return_code = unsafe { // REVIEW: Why does LLVM need a mutable ptr to path...? - llvm::LLVMTargetMachineEmitToFile( + llvm_sys::target_machine::LLVMTargetMachineEmitToFile( self.tm, - self.llmod(), + NonNull::from(self.llmod()).as_ptr(), path.as_ptr(), - llvm::CodeGenFileType::ObjectFile, + llvm_sys::target_machine::LLVMCodeGenFileType::LLVMObjectFile, err_string.as_mut_ptr(), ) }; @@ -272,8 +522,8 @@ impl ModuleLlvm { impl Drop for ModuleLlvm { fn drop(&mut self) { unsafe { - llvm::LLVMDisposeTargetMachine(&mut *(self.tm as *mut _)); - llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); + llvm_sys::target_machine::LLVMDisposeTargetMachine(&mut *(self.tm as *mut _)); + llvm_sys::core::LLVMContextDispose(&mut *(self.llcx as *mut _)); } } } diff --git a/openvaf/mir_llvm/src/types.rs b/openvaf/mir_llvm/src/types.rs index ee0cc42..f8033fc 100644 --- a/openvaf/mir_llvm/src/types.rs +++ b/openvaf/mir_llvm/src/types.rs @@ -1,7 +1,14 @@ use std::ffi::CString; use libc::c_uint; -use llvm::{False, LLVMInt8TypeInContext, True, Type, Value}; +use llvm_sys::core::LLVMInt8TypeInContext; +use llvm_sys::prelude::LLVMBool; +use llvm_sys::{LLVMType as Type, LLVMValue as Value}; + +const FALSE: LLVMBool = 0; +const TRUE: LLVMBool = 1; +use core::ptr::NonNull; + use mir::Const; use crate::CodegenCx; @@ -15,39 +22,61 @@ pub struct Types<'ll> { pub fat_ptr: &'ll Type, pub bool: &'ll Type, pub void: &'ll Type, - pub null_ptr_val: &'ll llvm::Value, + pub null_ptr_val: &'ll Value, } impl<'ll> Types<'ll> { - pub fn new(llcx: &'ll llvm::Context, pointer_width: u32) -> Types<'ll> { + pub fn new(llcx: &'ll llvm_sys::LLVMContext, pointer_width: u32) -> Types<'ll> { unsafe { - let char = LLVMInt8TypeInContext(llcx); + let char = LLVMInt8TypeInContext(NonNull::from(llcx).as_ptr()); // we are using opaque pointers, with old llvm version that plain // means always using char pointers, with newer llvm version the // type is ignored anyway - let ptr = llvm::LLVMPointerType(char, llvm::AddressSpace::DATA); - let size = llvm::LLVMIntTypeInContext(llcx, pointer_width); + //let ptr = llvm_sys::core::LLVMPointerType(char, llvm_sys::AddressSpace::DATA); + let ptr = llvm_sys::core::LLVMPointerType(char, 0); // 0 represents the default (DATA) address space + let size = + llvm_sys::core::LLVMIntTypeInContext(NonNull::from(llcx).as_ptr(), pointer_width); Types { - double: llvm::LLVMDoubleTypeInContext(llcx), - char, - int: llvm::LLVMInt32TypeInContext(llcx), - size, - ptr, - fat_ptr: ty_struct(llcx, "fat_ptr", &[ptr, llvm::LLVMInt64TypeInContext(llcx)]), - bool: llvm::LLVMInt1TypeInContext(llcx), - void: llvm::LLVMVoidTypeInContext(llcx), - null_ptr_val: llvm::LLVMConstPointerNull(ptr), + double: &*llvm_sys::core::LLVMDoubleTypeInContext(NonNull::from(llcx).as_ptr()), + char: &*char, + int: &*llvm_sys::core::LLVMInt32TypeInContext(NonNull::from(llcx).as_ptr()), + size: &*size, + ptr: &*ptr, + fat_ptr: ty_struct( + llcx, + "fat_ptr", + &[ + &*ptr, + &*llvm_sys::core::LLVMInt64TypeInContext(NonNull::from(llcx).as_ptr()), + ], + ), + bool: &*llvm_sys::core::LLVMInt1TypeInContext(NonNull::from(llcx).as_ptr()), + void: &*llvm_sys::core::LLVMVoidTypeInContext(NonNull::from(llcx).as_ptr()), + null_ptr_val: &*llvm_sys::core::LLVMConstPointerNull(ptr), } } } } - -fn ty_struct<'ll>(llcx: &'ll llvm::Context, name: &str, elements: &[&'ll Type]) -> &'ll Type { +fn ty_struct<'ll>( + llcx: &'ll llvm_sys::LLVMContext, + name: &str, + elements: &[&'ll Type], +) -> &'ll Type { let name = CString::new(name).unwrap(); unsafe { - let ty = llvm::LLVMStructCreateNamed(llcx, name.as_ptr()); - llvm::LLVMStructSetBody(ty, elements.as_ptr(), elements.len() as u32, False); - ty + let ty = llvm_sys::core::LLVMStructCreateNamed(NonNull::from(llcx).as_ptr(), name.as_ptr()); + + // Convert &[&'ll Type] to Vec<*mut LLVMType> + let mut element_ptrs: Vec<*mut llvm_sys::LLVMType> = + elements.iter().map(|&e| e as *const _ as *mut _).collect(); + + llvm_sys::core::LLVMStructSetBody( + ty, + element_ptrs.as_mut_ptr(), + elements.len() as u32, + 0, //false + ); + &*ty } } @@ -89,7 +118,7 @@ impl<'a, 'll> CodegenCx<'a, 'll> { self.tys.fat_ptr } pub fn ty_aint(&self, bits: u32) -> &'ll Type { - unsafe { llvm::LLVMIntTypeInContext(self.llcx, bits) } + unsafe { &*llvm_sys::core::LLVMIntTypeInContext(NonNull::from(self.llcx).as_ptr(), bits) } } pub fn ty_struct(&self, name: &str, elements: &[&'ll Type]) -> &'ll Type { @@ -97,15 +126,34 @@ impl<'a, 'll> CodegenCx<'a, 'll> { } pub fn ty_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { - unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) } - } + unsafe { + let mut arg_ptrs: Vec<*mut llvm_sys::LLVMType> = + args.iter().map(|&arg| arg as *const _ as *mut _).collect(); + &*llvm_sys::core::LLVMFunctionType( + ret as *const _ as *mut _, + arg_ptrs.as_mut_ptr(), + args.len() as c_uint, + FALSE, + ) + } + } pub fn ty_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { - unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } + unsafe { + let mut arg_ptrs: Vec<*mut llvm_sys::LLVMType> = + args.iter().map(|&arg| arg as *const _ as *mut _).collect(); + + &*llvm_sys::core::LLVMFunctionType( + ret as *const _ as *mut _, + arg_ptrs.as_mut_ptr(), + args.len() as c_uint, + TRUE, + ) + } } pub fn ty_array(&self, ty: &'ll Type, len: u32) -> &'ll Type { - unsafe { llvm::LLVMArrayType(ty, len) } + unsafe { &*llvm_sys::core::LLVMArrayType2(NonNull::from(ty).as_ptr(), len.into()) } } pub fn const_val(&self, val: &Const) -> &'ll Value { @@ -123,55 +171,104 @@ impl<'a, 'll> CodegenCx<'a, 'll> { /// The pointer must be a constant address pub unsafe fn const_gep( &self, - elem_ty: &'ll llvm::Type, - ptr: &'ll llvm::Value, - indices: &[&'ll llvm::Value], - ) -> &'ll llvm::Value { - llvm::LLVMConstInBoundsGEP2(elem_ty, ptr, indices.as_ptr(), indices.len() as u32) - } + elem_ty: &'ll Type, + ptr: &'ll Value, + indices: &[&'ll Value], + ) -> &'ll Value { + let mut index_ptrs: Vec<*mut llvm_sys::LLVMValue> = + indices.iter().map(|&v| NonNull::from(v).as_ptr()).collect(); + &*llvm_sys::core::LLVMConstInBoundsGEP2( + NonNull::from(elem_ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + index_ptrs.as_mut_ptr(), + indices.len() as u32, + ) + } pub fn const_int(&self, val: i32) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_int(), val as u64, True) } + unsafe { + &*llvm_sys::core::LLVMConstInt(NonNull::from(self.ty_int()).as_ptr(), val as u64, TRUE) + } } pub fn const_unsigned_int(&self, val: u32) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_int(), val as u64, True) } + unsafe { + &*llvm_sys::core::LLVMConstInt(NonNull::from(self.ty_int()).as_ptr(), val as u64, TRUE) + } } pub fn const_isize(&self, val: isize) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_size(), val as u64, True) } + unsafe { + &*llvm_sys::core::LLVMConstInt(NonNull::from(self.ty_size()).as_ptr(), val as u64, TRUE) + } } pub fn const_usize(&self, val: usize) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_size(), val as u64, False) } + unsafe { + &*llvm_sys::core::LLVMConstInt( + NonNull::from(self.ty_size()).as_ptr(), + val as u64, + FALSE, + ) + } } pub fn const_bool(&self, val: bool) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_bool(), val as u64, False) } + unsafe { + &*llvm_sys::core::LLVMConstInt( + NonNull::from(self.ty_bool()).as_ptr(), + val as u64, + FALSE, + ) + } } pub fn const_c_bool(&self, val: bool) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_c_bool(), val as u64, False) } + unsafe { + &*llvm_sys::core::LLVMConstInt( + NonNull::from(self.ty_c_bool()).as_ptr(), + val as u64, + FALSE, + ) + } } pub fn const_u8(&self, val: u8) -> &'ll Value { - unsafe { llvm::LLVMConstInt(self.ty_c_bool(), val as u64, False) } + unsafe { + &*llvm_sys::core::LLVMConstInt( + NonNull::from(self.ty_c_bool()).as_ptr(), + val as u64, + FALSE, + ) + } } pub fn const_real(&self, val: f64) -> &'ll Value { - unsafe { llvm::LLVMConstReal(self.ty_double(), val) } + unsafe { &*llvm_sys::core::LLVMConstReal(NonNull::from(self.ty_double()).as_ptr(), val) } } pub fn const_arr(&self, elem_ty: &'ll Type, vals: &[&'ll Value]) -> &'ll Value { - unsafe { llvm::LLVMConstArray(elem_ty, vals.as_ptr(), vals.len() as u32) } + unsafe { + let mut val_ptrs: Vec<*mut llvm_sys::LLVMValue> = + vals.iter().map(|&v| NonNull::from(v).as_ptr()).collect(); + &*llvm_sys::core::LLVMConstArray2( + NonNull::from(elem_ty).as_ptr(), + val_ptrs.as_mut_ptr(), + vals.len() as u64, + ) + } } pub fn const_struct(&self, ty: &'ll Type, vals: &[&'ll Value]) -> &'ll Value { - unsafe { llvm::LLVMConstNamedStruct(ty, vals.as_ptr(), vals.len() as u32) } - } - - pub fn const_null(&self, t: &'ll Type) -> &'ll Value { - unsafe { llvm::LLVMConstNull(t) } + unsafe { + let mut val_ptrs: Vec<*mut llvm_sys::LLVMValue> = + vals.iter().map(|&v| NonNull::from(v).as_ptr()).collect(); + &*llvm_sys::core::LLVMConstNamedStruct( + NonNull::from(ty).as_ptr(), + val_ptrs.as_mut_ptr(), + vals.len() as u32, + ) + } } pub fn const_null_ptr(&self) -> &'ll Value { @@ -179,10 +276,10 @@ impl<'a, 'll> CodegenCx<'a, 'll> { } pub fn const_undef(&self, t: &'ll Type) -> &'ll Value { - unsafe { llvm::LLVMGetUndef(t) } + unsafe { &*llvm_sys::core::LLVMGetUndef(NonNull::from(t).as_ptr()) } } pub fn val_ty(&self, v: &'ll Value) -> &'ll Type { - unsafe { llvm::LLVMTypeOf(v) } + unsafe { &*llvm_sys::core::LLVMTypeOf(NonNull::from(v).as_ptr()) } } } diff --git a/openvaf/openvaf-driver/Cargo.toml b/openvaf/openvaf-driver/Cargo.toml index dd27a5f..c5a2ea9 100644 --- a/openvaf/openvaf-driver/Cargo.toml +++ b/openvaf/openvaf-driver/Cargo.toml @@ -27,6 +27,7 @@ backtrace-ext = "0.2.1" backtrace = "0.3.68" mimalloc = { version = "*", default-features = false} +#llvm-sys = { version = "181.2.0", features = ["prefer-dynamic"] } [dev-dependencies] xshell = "0.2.3" diff --git a/openvaf/openvaf-driver/src/cli_process.rs b/openvaf/openvaf-driver/src/cli_process.rs index ad2ee55..bf50897 100644 --- a/openvaf/openvaf-driver/src/cli_process.rs +++ b/openvaf/openvaf-driver/src/cli_process.rs @@ -4,7 +4,9 @@ use std::process::exit; use anyhow::{bail, Context, Result}; use camino::Utf8PathBuf; use clap::ArgMatches; -use openvaf::{builtin_lints, get_target_names, host_triple, AbsPathBuf, LintLevel, OptLevel}; +use openvaf::{ + builtin_lints, get_target_names, host_triple, AbsPathBuf, LLVMCodeGenOptLevel, LintLevel, +}; use termcolor::{Color, ColorChoice, ColorSpec, WriteColor}; use crate::cli_def::{ @@ -83,10 +85,10 @@ pub fn matches_to_opts(matches: ArgMatches) -> Result { let include = include?; let opt_lvl = match &**matches.get_one::(OPT_LVL).unwrap() { - "0" => OptLevel::None, - "1" => OptLevel::Less, - "2" => OptLevel::Default, - "3" => OptLevel::Aggressive, + "0" => LLVMCodeGenOptLevel::LLVMCodeGenLevelNone, + "1" => LLVMCodeGenOptLevel::LLVMCodeGenLevelLess, + "2" => LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault, + "3" => LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive, lvl => bail!("unknown opt lvl {lvl}"), }; diff --git a/openvaf/openvaf-driver/src/crash_report.rs b/openvaf/openvaf-driver/src/crash_report.rs index 8fa5198..5dc56b1 100644 --- a/openvaf/openvaf-driver/src/crash_report.rs +++ b/openvaf/openvaf-driver/src/crash_report.rs @@ -6,7 +6,7 @@ use std::error::Error; use std::fmt::Write as FmtWrite; use std::fs::File; use std::io::Write; -use std::panic::PanicInfo; +use std::panic::PanicHookInfo; use std::path::{Path, PathBuf}; use std::{env, io, mem, panic}; @@ -15,7 +15,7 @@ use backtrace_ext::short_frames_strict; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; // Utility function which will handle dumping information to disk -pub fn handle_dump(panic_info: &PanicInfo) -> Option { +pub fn handle_dump(panic_info: &PanicHookInfo) -> Option { let mut expl = String::new(); #[cfg(feature = "nightly")] @@ -62,7 +62,7 @@ pub fn install_panic_handler() { return; } - panic::set_hook(Box::new(move |info: &PanicInfo| { + panic::set_hook(Box::new(move |info: &PanicHookInfo| { let file_path = handle_dump(info); print_msg(file_path).expect("printing error message to console failed"); })); diff --git a/openvaf/openvaf/Cargo.toml b/openvaf/openvaf/Cargo.toml index d3ed0d7..c9a858d 100644 --- a/openvaf/openvaf/Cargo.toml +++ b/openvaf/openvaf/Cargo.toml @@ -15,7 +15,8 @@ basedb = { version = "0.0.0", path = "../basedb" } sim_back = { version = "0.0.0", path = "../sim_back" } osdi = { version = "0.0.0", path = "../osdi" } -llvm = { version = "0.0.0", path = "../llvm" } +#llvm = { version = "0.0.0", path = "../llvm" } +llvm-sys = "181.1.1" mir_llvm = { version = "0.0.0", path = "../mir_llvm" } hir = { version = "0.0.0", path = "../hir" } target = { version = "0.0.0", path = "../target" } diff --git a/openvaf/openvaf/src/lib.rs b/openvaf/openvaf/src/lib.rs index 2f85e3d..91b1e1a 100644 --- a/openvaf/openvaf/src/lib.rs +++ b/openvaf/openvaf/src/lib.rs @@ -9,7 +9,7 @@ use basedb::BaseDB; use camino::Utf8PathBuf; use hir::CompilationDB; use linker::link; -pub use llvm::OptLevel; +pub use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mir_llvm::LLVMBackend; pub use paths::AbsPathBuf; use sim_back::collect_modules; @@ -39,7 +39,7 @@ pub struct Opts { pub input: Utf8PathBuf, pub output: CompilationDestination, pub include: Vec, - pub opt_lvl: OptLevel, + pub opt_lvl: LLVMCodeGenOptLevel, pub target: Target, pub target_cpu: String, } diff --git a/openvaf/openvaf/tests/integration.rs b/openvaf/openvaf/tests/integration.rs index 5050ae5..67e0311 100644 --- a/openvaf/openvaf/tests/integration.rs +++ b/openvaf/openvaf/tests/integration.rs @@ -4,7 +4,7 @@ use std::path::Path; use camino::Utf8Path; use expect_test::expect_file; use float_cmp::assert_approx_eq; -use llvm::OptLevel; +use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mini_harness::{harness, Result}; use openvaf::{CompilationDestination, CompilationTermination}; use stdx::{ignore_dev_tests, openvaf_test_data, project_root}; @@ -24,7 +24,7 @@ fn compile_and_load(root_file: &Utf8Path) -> &'static OsdiDescriptor { input: root_file.to_path_buf(), output: CompilationDestination::Path { lib_file: root_file.with_extension("osdi") }, include: Vec::new(), - opt_lvl: OptLevel::Aggressive, + opt_lvl: LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive, target: Target::host_target().unwrap(), target_cpu: "native".to_owned(), dry_run: false, diff --git a/openvaf/osdi/Cargo.toml b/openvaf/osdi/Cargo.toml index bd72e7b..7fe03c8 100644 --- a/openvaf/osdi/Cargo.toml +++ b/openvaf/osdi/Cargo.toml @@ -21,7 +21,8 @@ sim_back = { version = "0.0.0", path = "../sim_back" } mir = { version = "0.0.0", path = "../mir" } mir_llvm = { version = "0.0.0", path = "../mir_llvm" } -llvm = { version = "0.0.0", path = "../llvm" } +#llvm = { version = "0.0.0", path = "../llvm" } +llvm-sys = "181.1.1" target = { version = "0.0.0", path = "../target"} typed-index-collections = "3.1" @@ -30,7 +31,7 @@ lasso = {version = "0.7", features = ["ahash"]} salsa = "0.17.0-pre.2" indexmap = "2.0" -smol_str = {version = "0.2", default_features=false} +smol_str = {version = "0.2", default-features=false} base_n = {version = "1", path="../../lib/base_n"} rayon-core = "1" diff --git a/openvaf/osdi/src/access.rs b/openvaf/osdi/src/access.rs index 9efecfb..444da5c 100644 --- a/openvaf/osdi/src/access.rs +++ b/openvaf/osdi/src/access.rs @@ -1,15 +1,18 @@ -use llvm::IntPredicate::IntNE; -use llvm::{ +use core::ptr::NonNull; + +use llvm_sys::core::{ LLVMAddCase, LLVMAppendBasicBlockInContext, LLVMBuildAnd, LLVMBuildBr, LLVMBuildCondBr, LLVMBuildICmp, LLVMBuildRet, LLVMBuildSelect, LLVMBuildSwitch, LLVMCreateBuilderInContext, - LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, UNNAMED, + LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, }; +use llvm_sys::LLVMIntPredicate::LLVMIntNE; +use mir_llvm::UNNAMED; use crate::compilation_unit::OsdiCompilationUnit; use crate::metadata::osdi_0_4::{ACCESS_FLAG_INSTANCE, ACCESS_FLAG_SET}; impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { - pub fn access_function_prototype(&self) -> &'ll llvm::Value { + pub fn access_function_prototype(&self) -> &'ll llvm_sys::LLVMValue { let cx = &self.cx; let void_ptr = cx.ty_ptr(); let uint32_t = cx.ty_int(); @@ -18,30 +21,51 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { cx.declare_ext_fn(name, fun_ty) } - pub fn access_function(&self) -> &'ll llvm::Value { + pub fn access_function(&self) -> &'ll llvm_sys::LLVMValue { let llfunc = self.access_function_prototype(); let OsdiCompilationUnit { inst_data, model_data, cx, .. } = &self; unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let err_exit = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let model_bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let inst_bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let opvar_bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let err_exit = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let model_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let inst_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let opvar_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let model = LLVMGetParam(llfunc, 1); - let param_id = LLVMGetParam(llfunc, 2); - let flags = LLVMGetParam(llfunc, 3); + let inst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let model = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); + let param_id = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); + let flags = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3); // constants - let access_flag_instance = cx.const_unsigned_int(ACCESS_FLAG_INSTANCE); - let access_flag_set = cx.const_unsigned_int(ACCESS_FLAG_SET); - let zero = cx.const_unsigned_int(0); + let access_flag_instance = + NonNull::from(cx.const_unsigned_int(ACCESS_FLAG_INSTANCE)).as_ptr(); + let access_flag_set = NonNull::from(cx.const_unsigned_int(ACCESS_FLAG_SET)).as_ptr(); + let zero = NonNull::from(cx.const_unsigned_int(0)).as_ptr(); // // start building function body @@ -49,11 +73,11 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // compute boolean indicating if instance flag is set let flags_and_instance = LLVMBuildAnd(llbuilder, flags, access_flag_instance, UNNAMED); let instance_flag_set = - LLVMBuildICmp(llbuilder, IntNE, flags_and_instance, zero, UNNAMED); + LLVMBuildICmp(llbuilder, LLVMIntNE, flags_and_instance, zero, UNNAMED); // compute boolean indicating if write flag is set let flags_and_set = LLVMBuildAnd(llbuilder, flags, access_flag_set, UNNAMED); - let write_flag_set = LLVMBuildICmp(llbuilder, IntNE, flags_and_set, zero, UNNAMED); + let write_flag_set = LLVMBuildICmp(llbuilder, LLVMIntNE, flags_and_set, zero, UNNAMED); // build if block, true block is for instance flag set, false block is for instance flag not set LLVMBuildCondBr(llbuilder, instance_flag_set, inst_bb, model_bb); @@ -74,22 +98,33 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // assumes osdi ids of instance parameters are 0..inst_data.params.len() for param_idx in 0..inst_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb - let case = cx.const_unsigned_int(param_idx as u32); + let case = NonNull::from(cx.const_unsigned_int(param_idx as u32)).as_ptr(); LLVMAddCase(switch_inst, case, bb); // build code for retrieving pointer to parameter storage of // param_idx-th instance parameter in instance structure - let (ptr, _) = inst_data.nth_param_ptr(param_idx as u32, inst, llbuilder); + let (ptr, _) = inst_data.nth_param_ptr(param_idx as u32, &*inst, &*llbuilder); // set the param_given flag if write flag is given // create new block for writing - let write = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let write = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); // create new block for return - let ret = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - + let ret = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); // build if, true block is for setting write flag (write block), false block is return (ret block) LLVMBuildCondBr(llbuilder, write_flag_set, write, ret); @@ -97,14 +132,14 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMPositionBuilderAtEnd(llbuilder, write); // build code for setting the param_given flag - inst_data.set_nth_param_given(cx, param_idx as u32, inst, llbuilder); + inst_data.set_nth_param_given(cx, param_idx as u32, &*inst, &*llbuilder); // build branch (jump) to false block LLVMBuildBr(llbuilder, ret); // build false block // return the pointer LLVMPositionBuilderAtEnd(llbuilder, ret); - LLVMBuildRet(llbuilder, ptr); + LLVMBuildRet(llbuilder, NonNull::from(ptr).as_ptr()); } // @@ -125,57 +160,86 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // assumes osdi ids of instance parameters are 0..inst_data.params.len() for param_idx in 0..inst_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); - LLVMAddCase(switch_model, case, bb); + + LLVMAddCase(switch_model, NonNull::from(case).as_ptr(), bb); // build code for getting the pointer to // param_idx-th instance parameter in model structure - let (ptr, _) = - model_data.nth_inst_param_ptr(inst_data, param_idx as u32, model, llbuilder); + let (ptr, _) = model_data.nth_inst_param_ptr( + inst_data, + param_idx as u32, + &*model, + &*llbuilder, + ); // set the param_given flag if write flag is given - let write = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let ret = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let write = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let ret = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMBuildCondBr(llbuilder, write_flag_set, write, ret); LLVMPositionBuilderAtEnd(llbuilder, write); // build code for setting the param_given flag of an instance parameter in model structure - model_data.set_nth_inst_param_given(cx, param_idx as u32, model, llbuilder); + model_data.set_nth_inst_param_given(cx, param_idx as u32, &*model, &*llbuilder); LLVMBuildBr(llbuilder, ret); // return the pointer LLVMPositionBuilderAtEnd(llbuilder, ret); - LLVMBuildRet(llbuilder, ptr); + LLVMBuildRet(llbuilder, NonNull::from(ptr).as_ptr()); } // build cases, one for each model parameter // assumes osdi ids of model parameters start with inst_data.params.len() for param_idx in 0..model_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int((inst_data.params.len() + param_idx) as u32); - LLVMAddCase(switch_model, case, bb); + LLVMAddCase(switch_model, NonNull::from(case).as_ptr(), bb); // build code for getting the pointer to // param_idx-th model parameter in model structure - let (ptr, _) = model_data.nth_param_ptr(param_idx as u32, model, llbuilder); + let (ptr, _) = model_data.nth_param_ptr(param_idx as u32, &*model, &*llbuilder); // set the param_given flag if write flag is given - let write = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let ret = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let write = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let ret = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMBuildCondBr(llbuilder, write_flag_set, write, ret); LLVMPositionBuilderAtEnd(llbuilder, write); // build code for setting the param_given flag of a model parameter in model structure - model_data.set_nth_param_given(cx, param_idx as u32, model, llbuilder); + model_data.set_nth_param_given(cx, param_idx as u32, &*model, &*llbuilder); LLVMBuildBr(llbuilder, ret); // return the pointer LLVMPositionBuilderAtEnd(llbuilder, ret); - LLVMBuildRet(llbuilder, ptr); + LLVMBuildRet(llbuilder, NonNull::from(ptr).as_ptr()); } // null pointer constant @@ -194,25 +258,29 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // get inst_data, model_data, and cx let OsdiCompilationUnit { inst_data, model_data, cx, .. } = &self; // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int( (model_data.params.len() + inst_data.params.len() + opvar_idx) as u32, ); - LLVMAddCase(switch_opvar, case, bb); + + LLVMAddCase(switch_opvar, NonNull::from(case).as_ptr(), bb); // build code for getting the pointer to // param_idx-th opvar in instance structure - let (ptr, _) = self.nth_opvar_ptr(opvar_idx as u32, inst, model, llbuilder); - + let (ptr, _) = self.nth_opvar_ptr(opvar_idx as u32, &*inst, &*model, &*llbuilder); // return the pointer - LLVMBuildRet(llbuilder, ptr); + LLVMBuildRet(llbuilder, NonNull::from(ptr).as_ptr()); } // return NULL on unknown id LLVMPositionBuilderAtEnd(llbuilder, err_exit); - LLVMBuildRet(llbuilder, null_ptr); + LLVMBuildRet(llbuilder, NonNull::from(null_ptr).as_ptr()); LLVMDisposeBuilder(llbuilder); } @@ -220,7 +288,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { llfunc } - pub fn given_flag_instance(&self) -> &'ll llvm::Value { + pub fn given_flag_instance(&self) -> &'ll llvm_sys::LLVMValue { let cx = &self.cx; let void_ptr = cx.ty_ptr(); let uint32_t = cx.ty_int(); @@ -234,15 +302,23 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let zero = cx.const_int(0); let one = cx.const_int(1); - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let not_found = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let not_found = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let ptr = LLVMGetParam(llfunc, 0); - let param_id = LLVMGetParam(llfunc, 1); + let ptr = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let param_id = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); // // start building function body @@ -256,15 +332,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // assumes osdi ids of instance parameters are 0..inst_data.params.len() for param_idx in 0..inst_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); - LLVMAddCase(switch_inst, case, bb); + LLVMAddCase(switch_inst, NonNull::from(case).as_ptr(), bb); // Build code for checking the parameter given flag - let is_given = inst_data.is_nth_param_given(cx, param_idx as u32, ptr, llbuilder); - let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); + let is_given = + inst_data.is_nth_param_given(cx, param_idx as u32, &*ptr, &*llbuilder); + let is_given = LLVMBuildSelect( + llbuilder, + NonNull::from(is_given).as_ptr(), + NonNull::from(one).as_ptr(), + NonNull::from(zero).as_ptr(), + UNNAMED, + ); // Return value LLVMBuildRet(llbuilder, is_given); @@ -274,13 +361,16 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMPositionBuilderAtEnd(llbuilder, not_found); // Return 0 - LLVMBuildRet(llbuilder, zero); + LLVMBuildRet(llbuilder, NonNull::from(zero).as_ptr()); + + //Do we have to dispose this? + //LLVMDisposeBuilder(llbuilder); } llfunc } - pub fn given_flag_model(&self) -> &'ll llvm::Value { + pub fn given_flag_model(&self) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { inst_data, model_data, cx, .. } = &self; let args_ = [cx.ty_ptr(), cx.ty_int()]; let fun_ty = cx.ty_func(&args_, cx.ty_int()); @@ -291,15 +381,23 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let zero = cx.const_int(0); let one = cx.const_int(1); - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let not_found = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let not_found = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let ptr = LLVMGetParam(llfunc, 0); - let param_id = LLVMGetParam(llfunc, 1); + let ptr = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let param_id = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); // // start building function body @@ -317,16 +415,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // assumes osdi ids of instance parameters are 0..inst_data.params.len() for param_idx in 0..inst_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int(param_idx as u32); - LLVMAddCase(switch_inst, case, bb); + LLVMAddCase(switch_inst, NonNull::from(case).as_ptr(), bb); // Build code for checking the parameter given flag let is_given = - model_data.is_nth_inst_param_given(cx, param_idx as u32, ptr, llbuilder); - let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); + model_data.is_nth_inst_param_given(cx, param_idx as u32, &*ptr, &*llbuilder); + let is_given = LLVMBuildSelect( + llbuilder, + NonNull::from(is_given).as_ptr(), + NonNull::from(one).as_ptr(), + NonNull::from(zero).as_ptr(), + UNNAMED, + ); // Return value LLVMBuildRet(llbuilder, is_given); @@ -336,15 +444,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // assumes osdi ids of model parameters start with inst_data.params.len() for param_idx in 0..model_data.params.len() { // create building block bb - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); LLVMPositionBuilderAtEnd(llbuilder, bb); // construct case constant, add case with building block bb let case = cx.const_unsigned_int((inst_data.params.len() + param_idx) as u32); - LLVMAddCase(switch_inst, case, bb); + LLVMAddCase(switch_inst, NonNull::from(case).as_ptr(), bb); // Build code for checking the parameter given flag - let is_given = model_data.is_nth_param_given(cx, param_idx as u32, ptr, llbuilder); - let is_given = LLVMBuildSelect(llbuilder, is_given, one, zero, UNNAMED); + let is_given = + model_data.is_nth_param_given(cx, param_idx as u32, &*ptr, &*llbuilder); + let is_given = LLVMBuildSelect( + llbuilder, + NonNull::from(is_given).as_ptr(), + NonNull::from(one).as_ptr(), + NonNull::from(zero).as_ptr(), + UNNAMED, + ); // Return value LLVMBuildRet(llbuilder, is_given); @@ -354,7 +473,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { LLVMPositionBuilderAtEnd(llbuilder, not_found); // Return 0 - LLVMBuildRet(llbuilder, zero); + LLVMBuildRet(llbuilder, NonNull::from(zero).as_ptr()); + + //Do we have to dispose this? + //LLVMDisposeBuilder(llbuilder); } llfunc diff --git a/openvaf/osdi/src/bitfield.rs b/openvaf/osdi/src/bitfield.rs index 4fe4daa..89339fa 100644 --- a/openvaf/osdi/src/bitfield.rs +++ b/openvaf/osdi/src/bitfield.rs @@ -1,14 +1,12 @@ +use core::ptr::NonNull; use std::mem::size_of; -use llvm::IntPredicate::{IntEQ, IntNE}; -use llvm::{ +use llvm_sys::core::{ LLVMBuildAnd, LLVMBuildGEP2, LLVMBuildICmp, LLVMBuildLoad2, LLVMBuildOr, LLVMBuildStore, - UNNAMED, }; -use mir_llvm::{CodegenCx, MemLoc}; - +use llvm_sys::LLVMIntPredicate::{LLVMIntEQ, LLVMIntNE}; +use mir_llvm::{CodegenCx, MemLoc, UNNAMED}; type Word = u32; - const WORD_BYTES: u32 = size_of::() as u32; const WORD_BITS: u32 = WORD_BYTES * 8; @@ -22,58 +20,92 @@ fn word_cnt(len: u32) -> u32 { (len + WORD_BITS - 1) / WORD_BITS } -pub fn arr_ty<'ll>(len: u32, cx: &CodegenCx<'_, 'll>) -> &'ll llvm::Type { +pub fn arr_ty<'ll>(len: u32, cx: &CodegenCx<'_, 'll>) -> &'ll llvm_sys::LLVMType { cx.ty_array(cx.ty_int(), word_cnt(len)) } - pub unsafe fn word_ptr_and_mask<'ll>( cx: &CodegenCx<'_, 'll>, pos: u32, - arr_ptr: &'ll llvm::Value, - arr_ty: &'ll llvm::Type, - llbuilder: &llvm::Builder<'ll>, -) -> (&'ll llvm::Value, &'ll llvm::Value) { + arr_ptr: &'ll llvm_sys::LLVMValue, + arr_ty: &'ll llvm_sys::LLVMType, + llbuilder: &llvm_sys::LLVMBuilder, +) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMValue) { let (idx, mask) = word_index_and_mask(pos); let zero = cx.const_int(0); let pos = cx.const_unsigned_int(idx); - let word_ptr = LLVMBuildGEP2(llbuilder, arr_ty, arr_ptr, [zero, pos].as_ptr(), 2, UNNAMED); + + // Create an array of pointers without casting + let indices = [zero, pos]; + + let word_ptr = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(arr_ty).as_ptr(), + NonNull::from(arr_ptr).as_ptr(), + indices.as_ptr() as *mut *mut _, + 2, + UNNAMED, + ); + let mask = cx.const_unsigned_int(mask); - (word_ptr, mask) + // Convert the raw pointer back to a reference + (unsafe { &*word_ptr }, mask) } pub unsafe fn is_set<'ll>( cx: &CodegenCx<'_, 'll>, pos: u32, - arr_ptr: &'ll llvm::Value, - arr_ty: &'ll llvm::Type, - llbuilder: &llvm::Builder<'ll>, -) -> &'ll llvm::Value { + arr_ptr: &'ll llvm_sys::LLVMValue, + arr_ty: &'ll llvm_sys::LLVMType, + llbuilder: &llvm_sys::LLVMBuilder, +) -> &'ll llvm_sys::LLVMValue { let (ptr, mask) = word_ptr_and_mask(cx, pos, arr_ptr, arr_ty, llbuilder); - let word = LLVMBuildLoad2(llbuilder, cx.ty_int(), ptr, UNNAMED); - let is_set = LLVMBuildAnd(llbuilder, word, mask, UNNAMED); + let word = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_int()).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ); + let is_set = LLVMBuildAnd( + NonNull::from(llbuilder).as_ptr(), + word, + NonNull::from(mask).as_ptr(), + UNNAMED, + ); let zero = cx.const_int(0); - LLVMBuildICmp(llbuilder, IntNE, is_set, zero, UNNAMED) + &*LLVMBuildICmp( + NonNull::from(llbuilder).as_ptr(), + LLVMIntNE, + is_set, + NonNull::from(zero).as_ptr(), + UNNAMED, + ) } pub unsafe fn set_bit<'ll>( cx: &CodegenCx<'_, 'll>, pos: u32, - arr_ptr: &'ll llvm::Value, - arr_ty: &'ll llvm::Type, - llbuilder: &llvm::Builder<'ll>, + arr_ptr: &'ll llvm_sys::LLVMValue, + arr_ty: &'ll llvm_sys::LLVMType, + llbuilder: &llvm_sys::LLVMBuilder, ) { let (ptr, mask) = word_ptr_and_mask(cx, pos, arr_ptr, arr_ty, llbuilder); - let mut word = LLVMBuildLoad2(llbuilder, cx.ty_int(), ptr, UNNAMED); - word = LLVMBuildOr(llbuilder, word, mask, UNNAMED); - LLVMBuildStore(llbuilder, word, ptr); + let mut word = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_int()).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ); + word = + LLVMBuildOr(NonNull::from(llbuilder).as_ptr(), word, NonNull::from(mask).as_ptr(), UNNAMED); + LLVMBuildStore(NonNull::from(llbuilder).as_ptr(), word, NonNull::from(ptr).as_ptr()); } pub unsafe fn is_flag_set_mem<'ll>( cx: &CodegenCx<'_, 'll>, flag: u32, val: &MemLoc<'ll>, - llbuilder: &llvm::Builder<'ll>, -) -> &'ll llvm::Value { + llbuilder: &llvm_sys::LLVMBuilder, +) -> &'ll llvm_sys::LLVMValue { is_flag_set(cx, flag, val.read(llbuilder), llbuilder) } @@ -81,29 +113,55 @@ pub unsafe fn is_flag_set_mem<'ll>( // cx: &CodegenCx<'_, 'll>, // flag: u32, // val: MemLoc<'ll>, -// llbuilder: &llvm::Builder<'ll>, -// ) -> &'ll llvm::Value { +// llbuilder: &llvm_sys::LLVMBuilder, +// ) -> &'ll llvm_sys::LLVMValue { // is_flag_unset(cx, flag, val.read(llbuilder), llbuilder) // } pub unsafe fn is_flag_set<'ll>( cx: &CodegenCx<'_, 'll>, flag: u32, - val: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, -) -> &'ll llvm::Value { + val: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, +) -> &'ll llvm_sys::LLVMValue { let mask = cx.const_unsigned_int(flag); - let bits = LLVMBuildAnd(llbuilder, mask, val, UNNAMED); - LLVMBuildICmp(llbuilder, IntNE, bits, cx.const_int(0), UNNAMED) + let bits = LLVMBuildAnd( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(mask).as_ptr(), + NonNull::from(val).as_ptr(), + UNNAMED, + ); + unsafe { + &*LLVMBuildICmp( + NonNull::from(llbuilder).as_ptr(), + LLVMIntNE, + bits, + NonNull::from(cx.const_int(0)).as_ptr(), + UNNAMED, + ) + } } pub unsafe fn is_flag_unset<'ll>( cx: &CodegenCx<'_, 'll>, flag: u32, - val: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, -) -> &'ll llvm::Value { + val: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, +) -> &'ll llvm_sys::LLVMValue { let mask = cx.const_unsigned_int(flag); - let bits = LLVMBuildAnd(llbuilder, mask, val, UNNAMED); - LLVMBuildICmp(llbuilder, IntEQ, bits, cx.const_int(0), UNNAMED) + let bits = LLVMBuildAnd( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(mask).as_ptr(), + NonNull::from(val).as_ptr(), + UNNAMED, + ); + unsafe { + &*LLVMBuildICmp( + NonNull::from(llbuilder).as_ptr(), + LLVMIntEQ, + bits, + NonNull::from(cx.const_int(0)).as_ptr(), + UNNAMED, + ) + } } diff --git a/openvaf/osdi/src/compilation_unit.rs b/openvaf/osdi/src/compilation_unit.rs index e88fd98..08e8051 100644 --- a/openvaf/osdi/src/compilation_unit.rs +++ b/openvaf/osdi/src/compilation_unit.rs @@ -1,16 +1,20 @@ +use std::iter; +use std::ptr::NonNull; + use hir::CompilationDB; use hir_lower::fmt::{DisplayKind, FmtArg, FmtArgKind}; use hir_lower::{CallBackKind, HirInterner}; use lasso::Rodeo; -use llvm::{ - IntPredicate, LLVMAddIncoming, LLVMAppendBasicBlockInContext, LLVMBuildAdd, - LLVMBuildArrayMalloc, LLVMBuildBr, LLVMBuildCall2, LLVMBuildCondBr, LLVMBuildFMul, - LLVMBuildFree, LLVMBuildICmp, LLVMBuildInBoundsGEP2, LLVMBuildLoad2, LLVMBuildPhi, +use llvm_sys::core::{ + LLVMAddIncoming, LLVMAppendBasicBlockInContext, LLVMBuildAdd, LLVMBuildArrayMalloc, + LLVMBuildBr, LLVMBuildCall2, LLVMBuildCondBr, LLVMBuildFMul, LLVMBuildFree, LLVMBuildICmp, + LLVMBuildInBoundsGEP2, LLVMBuildLoad2, LLVMBuildPhi, LLVMGetFirstFunction, LLVMGetNextFunction, LLVMGetParam, LLVMIsDeclaration, LLVMPositionBuilderAtEnd, LLVMSetLinkage, - LLVMSetUnnamedAddress, Linkage, UnnamedAddr, UNNAMED, + LLVMSetUnnamedAddress, }; +use llvm_sys::{LLVMIntPredicate, LLVMLinkage, LLVMUnnamedAddr, LLVMValue}; use mir::{FuncRef, Function}; -use mir_llvm::{CallbackFun, CodegenCx, LLVMBackend, ModuleLlvm}; +use mir_llvm::{CallbackFun, CodegenCx, LLVMBackend, ModuleLlvm, UNNAMED}; use sim_back::dae::DaeSystem; use sim_back::init::Initialization; use sim_back::node_collapse::NodeCollapse; @@ -27,6 +31,20 @@ use crate::metadata::OsdiLimFunction; use crate::model_data::OsdiModelData; use crate::{lltype, OsdiLimId}; +fn function_iter( + module: &llvm_sys::LLVMModule, +) -> impl Iterator + '_ { + let fun = unsafe { LLVMGetFirstFunction(NonNull::from(module).as_ptr()) }; + iter::successors(Some(fun), |&fun| { + let next_fun = unsafe { LLVMGetNextFunction(fun) }; + if next_fun.is_null() { + None + } else { + Some(next_fun) + } + }) +} + pub fn new_codegen<'a, 'll>( back: &'a LLVMBackend, llmod: &'ll ModuleLlvm, @@ -35,15 +53,15 @@ pub fn new_codegen<'a, 'll>( let cx = unsafe { back.new_ctx(literals, llmod) }; cx.include_bitcode(stdlib_bitcode(back.target())); - for fun in llvm::function_iter(llmod.llmod()) { + for fun in function_iter(llmod.llmod()) { unsafe { // LLVMPurgeAttrs(fun); - if LLVMIsDeclaration(fun) != llvm::False { + if LLVMIsDeclaration(fun) != 0 as i32 { continue; } - LLVMSetLinkage(fun, Linkage::Internal); - LLVMSetUnnamedAddress(fun, UnnamedAddr::Global); + LLVMSetLinkage(fun, LLVMLinkage::LLVMInternalLinkage); + LLVMSetUnnamedAddress(fun, LLVMUnnamedAddr::LLVMGlobalUnnamedAddr); } } @@ -52,8 +70,8 @@ pub fn new_codegen<'a, 'll>( cx.get_declared_value("FMT_CHARS").expect("constant FMT_CHARS missing from stdlib"); unsafe { - LLVMSetLinkage(exp_table, Linkage::Internal); - LLVMSetLinkage(char_table, Linkage::Internal); + LLVMSetLinkage(NonNull::from(exp_table).as_ptr(), LLVMLinkage::LLVMInternalLinkage); + LLVMSetLinkage(NonNull::from(char_table).as_ptr(), LLVMLinkage::LLVMInternalLinkage); } cx @@ -66,7 +84,7 @@ pub struct OsdiCompilationUnit<'a, 'b, 'll> { pub tys: &'a OsdiTys<'ll>, pub cx: &'a CodegenCx<'b, 'll>, pub module: &'a OsdiModule<'b>, - pub lim_dispatch_table: Option<&'ll llvm::Value>, + pub lim_dispatch_table: Option<&'ll llvm_sys::LLVMValue>, } impl<'a, 'b, 'll> OsdiCompilationUnit<'a, 'b, 'll> { @@ -86,9 +104,18 @@ impl<'a, 'b, 'll> OsdiCompilationUnit<'a, 'b, 'll> { .define_global("OSDI_LIM_TABLE", ty) .unwrap_or_else(|| unreachable!("symbol OSDI_LIM_TABLE already defined")); unsafe { - llvm::LLVMSetLinkage(ptr, llvm::Linkage::ExternalLinkage); - llvm::LLVMSetUnnamedAddress(ptr, llvm::UnnamedAddr::No); - llvm::LLVMSetDLLStorageClass(ptr, llvm::DLLStorageClass::Export); + llvm_sys::core::LLVMSetLinkage( + NonNull::from(ptr).as_ptr(), + llvm_sys::LLVMLinkage::LLVMExternalLinkage, + ); + llvm_sys::core::LLVMSetUnnamedAddress( + NonNull::from(ptr).as_ptr(), + llvm_sys::LLVMUnnamedAddr::LLVMNoUnnamedAddr, + ); + llvm_sys::core::LLVMSetDLLStorageClass( + NonNull::from(ptr).as_ptr(), + llvm_sys::LLVMDLLStorageClass::LLVMDLLExportStorageClass, + ); } Some(ptr) } else { @@ -97,7 +124,7 @@ impl<'a, 'b, 'll> OsdiCompilationUnit<'a, 'b, 'll> { OsdiCompilationUnit { db, inst_data, model_data, tys, cx, module, lim_dispatch_table } } - pub fn lim_dispatch_table(&self) -> &'ll llvm::Value { + pub fn lim_dispatch_table(&self) -> &'ll llvm_sys::LLVMValue { self.lim_dispatch_table.unwrap() } } @@ -150,9 +177,9 @@ impl<'a> OsdiModule<'a> { pub fn general_callbacks<'ll>( intern: &HirInterner, builder: &mut mir_llvm::Builder<'_, '_, 'll>, - ret_flags: &'ll llvm::Value, - handle: &'ll llvm::Value, - simparam: &'ll llvm::Value, + ret_flags: &'ll llvm_sys::LLVMValue, + handle: &'ll llvm_sys::LLVMValue, + simparam: &'ll llvm_sys::LLVMValue, ) -> TiVec>> { let ptr_ty = builder.cx.ty_ptr(); intern @@ -234,29 +261,88 @@ pub fn general_callbacks<'ll>( }) .collect() } +/* This was very useful for debugging +fn print_module_ir(cx: &CodegenCx, message: &str) { + unsafe { + let ir_ptr = llvm_sys::core::LLVMPrintModuleToString(NonNull::from(cx.llmod).as_ptr()); + if !ir_ptr.is_null() { + let ir = std::ffi::CStr::from_ptr(ir_ptr).to_string_lossy().into_owned(); + let lines: Vec<&str> = ir.lines().collect(); + let mut found = false; + let mut count = 0; + let mut output_lines = Vec::new(); + + for line in lines { + if found { + output_lines.push(line); + count += 1; + if count >= 35 { + break; + } + } else if line.contains("internal fastcc void @cb.2(ptr %0, ptr %1) unnamed_addr") { + found = true; + output_lines.push(line); + count += 1; + } + } + + let output_str = output_lines.join("\n"); + println!("{}:\n{}", message, output_str); + llvm_sys::core::LLVMDisposeMessage(ir_ptr); + } + } +}*/ fn print_callback<'ll>( cx: &CodegenCx<'_, 'll>, kind: hir_lower::fmt::DisplayKind, arg_tys: &[FmtArg], -) -> (&'ll llvm::Value, &'ll llvm::Type) { +) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let mut args = vec![cx.ty_ptr(), cx.ty_ptr()]; args.extend(arg_tys.iter().map(|arg| lltype(&arg.ty, cx))); let fun_ty = cx.ty_func(&args, cx.ty_void()); let name = cx.local_callback_name(); let fun = cx.declare_int_fn(&name, fun_ty); + + // Print IR before starting the function + //print_module_ir(cx, "Before starting the function"); + unsafe { - let entry_bb = LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let alloc_bb = LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let write_bb = LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let err_bb = LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let exit_bb = LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let llbuilder = llvm::LLVMCreateBuilderInContext(cx.llcx); + let entry_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let alloc_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let write_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let err_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let exit_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let llbuilder = llvm_sys::core::LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry_bb); - let handle = LLVMGetParam(fun, 0); - let fmt_lit = LLVMGetParam(fun, 1); - let mut args = vec![cx.const_null_ptr(), cx.const_usize(0), LLVMGetParam(fun, 1)]; + let handle = LLVMGetParam(NonNull::from(fun).as_ptr(), 0); + let fmt_lit = LLVMGetParam(NonNull::from(fun).as_ptr(), 1); + let mut args = vec![ + cx.const_null_ptr(), + cx.const_usize(0), + &*LLVMGetParam(NonNull::from(fun).as_ptr(), 1), + ]; let exp_table = cx.get_declared_value("EXP").expect("constant EXP missing from stdlib"); let exp_table_ty = cx.ty_array(cx.ty_double(), 11); @@ -271,81 +357,149 @@ fn print_callback<'ll>( let mut free = Vec::new(); for (i, arg) in arg_tys.iter().enumerate() { - let val = LLVMGetParam(fun, i as u32 + 2); + let val = LLVMGetParam(NonNull::from(fun).as_ptr(), i as u32 + 2); match arg.kind { FmtArgKind::Binary => { + let mut val_array = [val]; let formatted_str = LLVMBuildCall2( llbuilder, - fmt_binary_ty, - fmt_binary, - [val].as_ptr(), + NonNull::from(fmt_binary_ty).as_ptr(), + NonNull::from(fmt_binary).as_ptr(), + val_array.as_mut_ptr(), 1, UNNAMED, ); free.push(formatted_str); } FmtArgKind::EngineerReal => { + let mut val_array = [val]; let idx = LLVMBuildCall2( llbuilder, - fmt_char_idx_ty, - fmt_char_idx, - [val].as_ptr(), + NonNull::from(fmt_char_idx_ty).as_ptr(), + NonNull::from(fmt_char_idx).as_ptr(), + val_array.as_mut_ptr(), 1, UNNAMED, ); + let mut idx_array = vec![cx.const_int(0), &*idx]; let exp = LLVMBuildInBoundsGEP2( llbuilder, - exp_table_ty, - exp_table, - [cx.const_int(0), idx].as_ptr(), + NonNull::from(exp_table_ty).as_ptr(), + NonNull::from(exp_table).as_ptr(), + idx_array.as_mut_ptr() as *mut *mut _, 2, UNNAMED, ); - let exp = LLVMBuildLoad2(llbuilder, cx.ty_double(), exp, UNNAMED); + let exp = LLVMBuildLoad2( + llbuilder, + NonNull::from(cx.ty_double()).as_ptr(), + exp, + UNNAMED, + ); let num = LLVMBuildFMul(llbuilder, val, exp, UNNAMED); - args.push(num); + args.push(&*num); + let mut idx_array = vec![cx.const_int(0), &*idx]; let scale_char = LLVMBuildInBoundsGEP2( llbuilder, - char_table_ty, - char_table, - [cx.const_int(0), idx].as_ptr(), + NonNull::from(char_table_ty).as_ptr(), + NonNull::from(char_table).as_ptr(), + idx_array.as_mut_ptr() as *mut *mut _, 2, UNNAMED, ); - args.push(scale_char); + args.push(&*scale_char); } - FmtArgKind::Other => args.push(val), + FmtArgKind::Other => args.push(&*val), } } - args.extend((1..(2 + arg_tys.len())).map(|arg| LLVMGetParam(fun, arg as u32))); + args.extend( + (1..(2 + arg_tys.len())) + .map(|arg| &*LLVMGetParam(NonNull::from(fun).as_ptr(), arg as u32)), + ); let (fun_ty, fun) = cx.intrinsic("snprintf").unwrap(); - let len = LLVMBuildCall2(llbuilder, fun_ty, fun, args.as_ptr(), args.len() as u32, UNNAMED); - let is_err = LLVMBuildICmp(llbuilder, IntPredicate::IntSLT, len, cx.const_int(0), UNNAMED); + // Convert Vec<&LLVMValue> to Vec<*mut LLVMValue> + let mut raw_args: Vec<*mut LLVMValue> = + args.iter().map(|&arg| NonNull::from(arg).as_ptr()).collect(); + + let len = LLVMBuildCall2( + llbuilder, + NonNull::from(fun_ty).as_ptr(), + NonNull::from(fun).as_ptr(), + raw_args.as_mut_ptr(), + raw_args.len() as u32, + UNNAMED, + ); + + let is_err = LLVMBuildICmp( + llbuilder, + LLVMIntPredicate::LLVMIntSLT, + len, + NonNull::from(cx.const_int(0)).as_ptr(), + UNNAMED, + ); LLVMBuildCondBr(llbuilder, is_err, err_bb, alloc_bb); + // Print IR after building the conditional branch + //print_module_ir(cx, "After building the conditional branch"); + LLVMPositionBuilderAtEnd(llbuilder, alloc_bb); - let data_len = LLVMBuildAdd(llbuilder, len, cx.const_int(1), UNNAMED); - let ptr = LLVMBuildArrayMalloc(llbuilder, cx.ty_char(), data_len, UNNAMED); + let data_len = + LLVMBuildAdd(llbuilder, len, NonNull::from(cx.const_int(1)).as_ptr(), UNNAMED); + let ptr = LLVMBuildArrayMalloc( + llbuilder, + NonNull::from(cx.ty_char()).as_ptr(), + data_len, + UNNAMED, + ); let null_ptr = cx.const_null_ptr(); - let is_err = LLVMBuildICmp(llbuilder, llvm::IntPredicate::IntEQ, null_ptr, ptr, UNNAMED); + let is_err = LLVMBuildICmp( + llbuilder, + llvm_sys::LLVMIntPredicate::LLVMIntEQ, + NonNull::from(null_ptr).as_ptr(), + ptr, + UNNAMED, + ); LLVMBuildCondBr(llbuilder, is_err, err_bb, write_bb); + // Print IR after building the malloc and conditional branch + //print_module_ir(cx, "After building the malloc and conditional branch"); + LLVMPositionBuilderAtEnd(llbuilder, write_bb); - let data_len = LLVMBuildAdd(llbuilder, len, cx.const_int(1), UNNAMED); - args[0] = ptr; - args[1] = data_len; - let len = LLVMBuildCall2(llbuilder, fun_ty, fun, args.as_ptr(), args.len() as u32, UNNAMED); - let is_err = LLVMBuildICmp(llbuilder, IntPredicate::IntSLT, len, cx.const_int(0), UNNAMED); + let data_len = + LLVMBuildAdd(llbuilder, len, NonNull::from(cx.const_int(1)).as_ptr(), UNNAMED); + raw_args[0] = ptr; + raw_args[1] = data_len; + let len = LLVMBuildCall2( + llbuilder, + NonNull::from(fun_ty).as_ptr(), + NonNull::from(fun).as_ptr(), + raw_args.as_mut_ptr(), + raw_args.len() as u32, + UNNAMED, + ); + let is_err = LLVMBuildICmp( + llbuilder, + LLVMIntPredicate::LLVMIntSLT, + len, + NonNull::from(cx.const_int(0)).as_ptr(), + UNNAMED, + ); for alloc in free.iter() { - LLVMBuildFree(llbuilder, alloc); + LLVMBuildFree(llbuilder, *alloc); } LLVMBuildCondBr(llbuilder, is_err, err_bb, exit_bb); + // Print IR after building the write block + //print_module_ir(cx, "After building the write block"); + LLVMPositionBuilderAtEnd(llbuilder, err_bb); LLVMBuildBr(llbuilder, exit_bb); + // Print IR after building the error block + //print_module_ir(cx, "After building the error block"); + LLVMPositionBuilderAtEnd(llbuilder, exit_bb); - let flags = LLVMBuildPhi(llbuilder, cx.ty_int(), UNNAMED); + let flags = LLVMBuildPhi(llbuilder, NonNull::from(cx.ty_int()).as_ptr(), UNNAMED); let lvl = match kind { DisplayKind::Debug => LOG_LVL_DEBUG, DisplayKind::Display | DisplayKind::Monitor => LOG_LVL_DISPLAY, @@ -357,16 +511,49 @@ fn print_callback<'ll>( let lvl_and_err = lvl | LOG_FMT_ERR; let lvl = cx.const_unsigned_int(lvl); let lvl_and_err = cx.const_unsigned_int(lvl_and_err); - LLVMAddIncoming(flags, [lvl, lvl_and_err].as_ptr(), [write_bb, err_bb].as_ptr(), 2); - let msg = LLVMBuildPhi(llbuilder, cx.ty_ptr(), UNNAMED); - LLVMAddIncoming(msg, [ptr, fmt_lit].as_ptr(), [write_bb, err_bb].as_ptr(), 2); + + let lvl_val = lvl as *const llvm_sys::LLVMValue as *mut _; + let lvl_and_err_val = lvl_and_err as *const llvm_sys::LLVMValue as *mut _; + let mut incoming_values: [*mut llvm_sys::LLVMValue; 2] = [lvl_val, lvl_and_err_val]; + let incoming_values_ptr = &mut incoming_values as *mut [*mut llvm_sys::LLVMValue] + as *mut *mut llvm_sys::LLVMValue; + + let mut incoming_blocks = [write_bb, err_bb]; + LLVMAddIncoming(flags, incoming_values_ptr, incoming_blocks.as_mut_ptr(), 2); + + let msg = LLVMBuildPhi(llbuilder, NonNull::from(cx.ty_ptr()).as_ptr(), UNNAMED); + // print_module_ir(cx, "After building the PHI block"); + + // Fix for second LLVMAddIncoming call + let mut incoming_values = [ptr, fmt_lit]; + let mut incoming_blocks = [write_bb, err_bb]; + LLVMAddIncoming(msg, incoming_values.as_mut_ptr(), incoming_blocks.as_mut_ptr(), 2); + let fun_ptr = cx.get_declared_value("osdi_log").expect("symbol osdi_log is missing"); let fun_ty = cx.ty_func(&[cx.ty_ptr(), cx.ty_ptr(), cx.ty_int()], cx.ty_void()); - let fun = LLVMBuildLoad2(llbuilder, cx.ty_ptr(), fun_ptr, UNNAMED); - LLVMBuildCall2(llbuilder, fun_ty, fun, [handle, msg, flags].as_ptr(), 3, UNNAMED); - llvm::LLVMBuildRetVoid(llbuilder); - llvm::LLVMDisposeBuilder(llbuilder); + let fun = LLVMBuildLoad2( + llbuilder, + NonNull::from(cx.ty_ptr()).as_ptr(), + NonNull::from(fun_ptr).as_ptr(), + UNNAMED, + ); + + // Fix for LLVMBuildCall2 + let mut args = [handle, msg, flags]; + LLVMBuildCall2( + llbuilder, + NonNull::from(fun_ty).as_ptr(), + fun, + args.as_mut_ptr(), + 3, + UNNAMED, + ); + llvm_sys::core::LLVMBuildRetVoid(llbuilder); + llvm_sys::core::LLVMDisposeBuilder(llbuilder); } + // Print IR at the end of the function + //print_module_ir(cx, "Final IR after building the function"); + (fun, fun_ty) } diff --git a/openvaf/osdi/src/eval.rs b/openvaf/osdi/src/eval.rs index f98a179..ccf2c2e 100644 --- a/openvaf/osdi/src/eval.rs +++ b/openvaf/osdi/src/eval.rs @@ -1,13 +1,15 @@ +use core::ptr::NonNull; + use hir_lower::{CallBackKind, CurrentKind, LimitState, ParamKind}; -use llvm::IntPredicate::{IntNE, IntULT}; -use llvm::{ +use llvm_sys::core::{ LLVMAppendBasicBlockInContext, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildBr, LLVMBuildCall2, LLVMBuildCondBr, LLVMBuildICmp, LLVMBuildInBoundsGEP2, LLVMBuildIntCast2, LLVMBuildLoad2, LLVMBuildOr, LLVMBuildRet, LLVMBuildStore, LLVMCreateBuilderInContext, LLVMDisposeBuilder, - LLVMGetParam, LLVMPositionBuilderAtEnd, UNNAMED, + LLVMGetParam, LLVMPositionBuilderAtEnd, }; +use llvm_sys::LLVMIntPredicate::{LLVMIntNE, LLVMIntULT}; use log::info; -use mir_llvm::{Builder, BuilderVal, CallbackFun, MemLoc}; +use mir_llvm::{Builder, BuilderVal, CallbackFun, MemLoc, UNNAMED}; use sim_back::SimUnknownKind; use typed_index_collections::TiVec; @@ -21,9 +23,8 @@ use crate::metadata::osdi_0_4::{ }; use crate::metadata::OsdiLimFunction; use crate::OsdiLimId; - impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { - pub fn eval_prototype(&self) -> &'ll llvm::Value { + pub fn eval_prototype(&self) -> &'ll llvm_sys::LLVMValue { let name = &format!("eval_{}", &self.module.sym); let cx = &self.cx; @@ -33,7 +34,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { cx.declare_ext_fn(name, fun_ty) } - pub fn eval(&self) -> &'ll llvm::Value { + pub fn eval(&self) -> &'ll llvm_sys::LLVMValue { let llfunc = self.eval_prototype(); let OsdiCompilationUnit { inst_data, model_data, cx, module, .. } = self; @@ -42,10 +43,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let mut builder = Builder::new(cx, func, llfunc); - let handle = unsafe { llvm::LLVMGetParam(llfunc, 0) }; - let instance = unsafe { llvm::LLVMGetParam(llfunc, 1) }; - let model = unsafe { llvm::LLVMGetParam(llfunc, 2) }; - let sim_info = unsafe { llvm::LLVMGetParam(llfunc, 3) }; + let handle = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0) }; + let instance = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1) }; + let model = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2) }; + let sim_info = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3) }; let sim_info_ty = self.tys.osdi_sim_info; // let simparam_ty = self.tys.osdi_sim_paras; @@ -73,7 +74,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let ret_flags = unsafe { builder.alloca(cx.ty_int()) }; unsafe { builder.store(ret_flags, cx.const_int(0)) }; - let connected_ports = unsafe { inst_data.load_connected_ports(&builder, instance) }; + let connected_ports = unsafe { inst_data.load_connected_ports(&mut builder, instance) }; let prev_solve: TiVec<_, _> = module .dae_system .unknowns @@ -118,7 +119,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let hi = get_prev_solve(SimUnknownKind::KirchoffLaw(hi)); if let Some(lo) = lo { let lo = get_prev_solve(SimUnknownKind::KirchoffLaw(lo)); - llvm::LLVMBuildFSub(builder.llbuilder, hi, lo, UNNAMED) + &*llvm_sys::core::LLVMBuildFSub( + builder.llbuilder, + NonNull::from(hi).as_ptr(), + NonNull::from(lo).as_ptr(), + UNNAMED, + ) } else { hi } @@ -172,7 +178,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { .unknowns .unwrap_index(&SimUnknownKind::KirchoffLaw(port)); let id = cx.const_unsigned_int(id.into()); - builder.int_cmp(id, connected_ports, IntULT) + builder.int_cmp(id, connected_ports, LLVMIntULT) } ParamKind::ParamSysFun(param) => inst_data .read_param( @@ -188,7 +194,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { is_flag_set(cx, CALC_REACT_JACOBIAN, flags, builder.llbuilder); let is_not_ic = is_flag_unset(cx, ANALYSIS_IC, flags, builder.llbuilder); - LLVMBuildAnd(builder.llbuilder, is_not_dc, is_not_ic, UNNAMED) + &*LLVMBuildAnd( + builder.llbuilder, + NonNull::from(is_not_dc).as_ptr(), + NonNull::from(is_not_ic).as_ptr(), + UNNAMED, + ) } ParamKind::PrevState(state) => { let idx = @@ -293,42 +304,60 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { (CALC_RESIST_JACOBIAN, CALC_RESIST_RESIDUAL, CALC_RESIST_LIM_RHS) }; - let store_matrix = |builder: &Builder<'_, '_, 'll>| { + let store_matrix = |builder: &mut Builder<'_, '_, 'll>| { for entry in module.dae_system.jacobian.keys() { inst_data.store_jacobian(entry, instance, builder, reactive) } }; - Self::build_store_results(&builder, llfunc, &flags, jacobian_flag, &store_matrix); - - let store_residual = |builder: &Builder<'_, '_, 'll>| { + Self::build_store_results( + &mut builder, + llfunc, + &flags, + jacobian_flag, + &store_matrix, + ); + + let store_residual = |builder: &mut Builder<'_, '_, 'll>| { for unknown in module.dae_system.unknowns.indices() { inst_data.store_residual(unknown, instance, builder, reactive); } }; - Self::build_store_results(&builder, llfunc, &flags, residual_flag, &store_residual); - - let store_lim_rhs = |builder: &Builder<'_, '_, 'll>| { + Self::build_store_results( + &mut builder, + llfunc, + &flags, + residual_flag, + &store_residual, + ); + + let store_lim_rhs = |builder: &mut Builder<'_, '_, 'll>| { for unknown in module.dae_system.unknowns.indices() { inst_data.store_lim_rhs(unknown, instance, builder, reactive); } }; - Self::build_store_results(&builder, llfunc, &flags, lim_rhs_flag, &store_lim_rhs); + Self::build_store_results( + &mut builder, + llfunc, + &flags, + lim_rhs_flag, + &store_lim_rhs, + ); } - let store_opvars = |builder: &Builder<'_, '_, 'll>| { + let store_opvars = |builder: &mut Builder<'_, '_, 'll>| { for (_, &eval_output) in &inst_data.opvars { inst_data.store_eval_output(eval_output, instance, builder) } }; - Self::build_store_results(&builder, llfunc, &flags, CALC_OP, &store_opvars); - let store_noise = |builder: &Builder<'_, '_, 'll>| { + Self::build_store_results(&mut builder, llfunc, &flags, CALC_OP, &store_opvars); + let store_noise = |builder: &mut Builder<'_, '_, 'll>| { for source in &inst_data.noise { for eval_output in source.eval_outputs() { inst_data.store_eval_output(eval_output, instance, builder) } } }; - Self::build_store_results(&builder, llfunc, &flags, CALC_NOISE, &store_noise); + Self::build_store_results(&mut builder, llfunc, &flags, CALC_NOISE, &store_noise); inst_data.store_bound_step(instance, &builder); @@ -340,18 +369,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } unsafe fn build_store_results( - builder: &Builder<'_, '_, 'll>, - llfunc: &'ll llvm::Value, + builder: &mut Builder<'_, '_, 'll>, + llfunc: &'ll llvm_sys::LLVMValue, flags: &MemLoc<'ll>, flag: u32, - store_val: &dyn Fn(&Builder<'_, '_, 'll>), + store_val: &dyn Fn(&mut Builder<'_, '_, 'll>), ) { let cx = builder.cx; - let bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let next_bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); + let bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let next_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); let is_set = is_flag_set_mem(cx, flag, flags, builder.llbuilder); - LLVMBuildCondBr(builder.llbuilder, is_set, bb, next_bb); + LLVMBuildCondBr(builder.llbuilder, NonNull::from(is_set).as_ptr(), bb, next_bb); LLVMPositionBuilderAtEnd(builder.llbuilder, bb); store_val(builder); @@ -365,7 +402,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { id: OsdiLimId, num_args: u32, flags_loc: &MemLoc<'ll>, - ret_flags_ptr: &'ll llvm::Value, + ret_flags_ptr: &'ll llvm_sys::LLVMValue, ) -> CallbackFun<'ll> { let OsdiCompilationUnit { cx, tys, .. } = self; let table = self.lim_dispatch_table(); @@ -381,65 +418,120 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let exit = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let val_changed_bb = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); - LLVMPositionBuilderAtEnd(llbuilder, entry); - - let mut flags = LLVMGetParam(llfunc, 0); - flags = flags_loc.read_with_ptr(llbuilder, flags); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let exit = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let val_changed_bb = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = &*LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); + LLVMPositionBuilderAtEnd(NonNull::from(llbuilder).as_ptr(), entry); + + let mut flags = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + flags = &*flags_loc + .read_with_ptr(NonNull::from(llbuilder).as_ptr(), NonNull::from(flags).as_ptr()); let mut init = is_flag_set(cx, INIT_LIM, flags, llbuilder); - init = LLVMBuildIntCast2(llbuilder, init, c_bool, llvm::False, UNNAMED); + init = &*LLVMBuildIntCast2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(init).as_ptr(), + NonNull::from(c_bool).as_ptr(), + 0, + UNNAMED, + ); - let mut val_changed = LLVMBuildAlloca(llbuilder, c_bool, UNNAMED); - LLVMBuildStore(llbuilder, cx.const_c_bool(false), val_changed); + let mut val_changed = LLVMBuildAlloca( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(c_bool).as_ptr(), + UNNAMED, + ); + LLVMBuildStore( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.const_c_bool(false)).as_ptr(), + val_changed, + ); + let id_val = cx.const_unsigned_int(id.into()) as *const llvm_sys::LLVMValue as *mut _; + let two_val = cx.const_int(2) as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [id_val, two_val]; + let gep_ptr = gep_indices.as_mut_ptr(); let func_ptr_ptr = LLVMBuildInBoundsGEP2( - llbuilder, - tys.osdi_lim_function, - table, - [cx.const_unsigned_int(id.into()), cx.const_int(2)].as_ptr(), + NonNull::from(llbuilder).as_ptr(), + NonNull::from(tys.osdi_lim_function).as_ptr(), + NonNull::from(table).as_ptr(), + gep_ptr, 2, UNNAMED, ); - let func_ptr = LLVMBuildLoad2(llbuilder, cx.ty_ptr(), func_ptr_ptr, UNNAMED); + let func_ptr = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_ptr()).as_ptr(), + func_ptr_ptr, + UNNAMED, + ); let mut lim_fn_args = vec![c_bool, cx.ty_ptr(), double, double]; lim_fn_args.extend((0..num_args).map(|_| double)); let lim_fn_ty = cx.ty_func(&lim_fn_args, double); - let mut args = vec![init, val_changed]; - args.extend((2..4 + num_args).map(|i| LLVMGetParam(llfunc, i))); + let mut args = vec![init, &*val_changed]; + args.extend( + (2..4 + num_args).map(|i| &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), i)), + ); + let mut raw_args: Vec<*mut llvm_sys::LLVMValue> = + args.iter().map(|&arg| arg as *const _ as *mut _).collect(); let res = LLVMBuildCall2( - llbuilder, - lim_fn_ty, + NonNull::from(llbuilder).as_ptr(), + NonNull::from(lim_fn_ty).as_ptr(), func_ptr, - args.as_ptr(), + raw_args.as_mut_ptr(), args.len() as u32, UNNAMED, ); - val_changed = LLVMBuildLoad2(llbuilder, c_bool, val_changed, UNNAMED); - val_changed = - LLVMBuildICmp(llbuilder, IntNE, val_changed, cx.const_c_bool(false), UNNAMED); - LLVMBuildCondBr(llbuilder, val_changed, val_changed_bb, exit); - - LLVMPositionBuilderAtEnd(llbuilder, val_changed_bb); - let ret_flags_ptr = LLVMGetParam(llfunc, 1); - let mut ret_flags = LLVMBuildLoad2(llbuilder, int, ret_flags_ptr, UNNAMED); + val_changed = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(c_bool).as_ptr(), + val_changed, + UNNAMED, + ); + val_changed = LLVMBuildICmp( + NonNull::from(llbuilder).as_ptr(), + LLVMIntNE, + val_changed, + NonNull::from(cx.const_c_bool(false)).as_ptr(), + UNNAMED, + ); + LLVMBuildCondBr(NonNull::from(llbuilder).as_ptr(), val_changed, val_changed_bb, exit); + + LLVMPositionBuilderAtEnd(NonNull::from(llbuilder).as_ptr(), val_changed_bb); + let ret_flags_ptr = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); + let mut ret_flags = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(int).as_ptr(), + ret_flags_ptr, + UNNAMED, + ); ret_flags = LLVMBuildOr( - llbuilder, + NonNull::from(llbuilder).as_ptr(), ret_flags, - cx.const_unsigned_int(EVAL_RET_FLAG_LIM), + NonNull::from(cx.const_unsigned_int(EVAL_RET_FLAG_LIM)).as_ptr(), UNNAMED, ); - LLVMBuildStore(llbuilder, ret_flags, ret_flags_ptr); - LLVMBuildBr(llbuilder, exit); + LLVMBuildStore(NonNull::from(llbuilder).as_ptr(), ret_flags, ret_flags_ptr); + LLVMBuildBr(NonNull::from(llbuilder).as_ptr(), exit); - LLVMPositionBuilderAtEnd(llbuilder, exit); - LLVMBuildRet(llbuilder, res); + LLVMPositionBuilderAtEnd(NonNull::from(llbuilder).as_ptr(), exit); + LLVMBuildRet(NonNull::from(llbuilder).as_ptr(), res); - LLVMDisposeBuilder(llbuilder); + LLVMDisposeBuilder(NonNull::from(llbuilder).as_ptr()); } CallbackFun { diff --git a/openvaf/osdi/src/inst_data.rs b/openvaf/osdi/src/inst_data.rs index 5798d24..189aa85 100644 --- a/openvaf/osdi/src/inst_data.rs +++ b/openvaf/osdi/src/inst_data.rs @@ -1,14 +1,26 @@ +use core::ffi::c_uint; +use core::ptr::NonNull; + use ahash::RandomState; use hir::{CompilationDB, ParamSysFun, Parameter, Variable}; use hir_lower::{HirInterner, LimitState, ParamKind, PlaceKind}; use indexmap::IndexMap; -use llvm::{ - IntPredicate, LLVMBuildFAdd, LLVMBuildFSub, LLVMBuildGEP2, LLVMBuildICmp, LLVMBuildIntCast2, - LLVMBuildLoad2, LLVMBuildStore, LLVMBuildStructGEP2, LLVMConstInt, LLVMOffsetOfElement, - LLVMSetFastMath, TargetData, UNNAMED, +use llvm_sys::core::{ + LLVMBuildFAdd, + LLVMBuildFSub, + LLVMBuildGEP2, + LLVMBuildICmp, + LLVMBuildIntCast2, + LLVMBuildLoad2, + LLVMBuildStore, + LLVMBuildStructGEP2, + LLVMConstInt, + // LLVMSetFastMath }; +use llvm_sys::target::{LLVMOffsetOfElement, LLVMTargetDataRef}; +use llvm_sys::LLVMIntPredicate; use mir::{strip_optbarrier, Const, Function, Param, ValueDef, F_ZERO}; -use mir_llvm::{CodegenCx, MemLoc}; +use mir_llvm::{CodegenCx, MemLoc, UNNAMED}; use sim_back::dae::{self, MatrixEntryId, SimUnknown}; use sim_back::init::CacheSlot; use stdx::packed_option::PackedOption; @@ -49,9 +61,9 @@ impl EvalOutput { fn new<'ll>( module: &OsdiModule<'_>, val: mir::Value, - eval_outputs: &mut TiMap, + eval_outputs: &mut TiMap, requires_slot: bool, - ty: &'ll llvm::Type, + ty: &'ll llvm_sys::LLVMType, ) -> EvalOutput { match module.eval.dfg.value_def(val) { ValueDef::Result(_, _) => (), @@ -98,8 +110,8 @@ pub struct Residual { impl Residual { pub fn new<'ll>( residual: &dae::Residual, - slots: &mut TiMap, - ty_real: &'ll llvm::Type, + slots: &mut TiMap, + ty_real: &'ll llvm_sys::LLVMType, func: &Function, ) -> Residual { let mut get_slot = |mut val| { @@ -130,8 +142,8 @@ impl MatrixEntry { pub fn new<'ll>( entry: &dae::MatrixEntry, module: &OsdiModule<'_>, - slots: &mut TiMap, - ty_real: &'ll llvm::Type, + slots: &mut TiMap, + ty_real: &'ll llvm_sys::LLVMType, num_react: &mut u32, ) -> MatrixEntry { let mut get_output = |mut val| { @@ -167,8 +179,8 @@ impl NoiseSource { pub fn new<'ll>( source: &dae::NoiseSource, module: &OsdiModule<'_>, - slots: &mut TiMap, - ty_real: &'ll llvm::Type, + slots: &mut TiMap, + ty_real: &'ll llvm_sys::LLVMType, ) -> NoiseSource { let mut get_output = |mut val| { val = strip_optbarrier(module.eval, val); @@ -189,20 +201,20 @@ impl NoiseSource { pub struct OsdiInstanceData<'ll> { /// llvm type for the instance data struct - pub ty: &'ll llvm::Type, + pub ty: &'ll llvm_sys::LLVMType, // llvm types for static (always present) instance data struct fields - pub param_given: &'ll llvm::Type, - pub jacobian_ptr: &'ll llvm::Type, - pub jacobian_ptr_react: &'ll llvm::Type, - pub node_mapping: &'ll llvm::Type, - pub state_idx: &'ll llvm::Type, - pub collapsed: &'ll llvm::Type, + pub param_given: &'ll llvm_sys::LLVMType, + pub jacobian_ptr: &'ll llvm_sys::LLVMType, + pub jacobian_ptr_react: &'ll llvm_sys::LLVMType, + pub node_mapping: &'ll llvm_sys::LLVMType, + pub state_idx: &'ll llvm_sys::LLVMType, + pub collapsed: &'ll llvm_sys::LLVMType, // llvm types for dynamic instance data struct fields - pub params: IndexMap, - pub eval_outputs: TiMap, - pub cache_slots: TiVec, + pub params: IndexMap, + pub eval_outputs: TiMap, + pub cache_slots: TiVec, pub residual: TiVec, pub noise: Vec, @@ -328,7 +340,7 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn store_bound_step( &self, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, ) { if let Some(slot) = self.bound_step { @@ -344,24 +356,36 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn param_ptr( &self, param: OsdiInstanceParam, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> Option<(&'ll llvm::Value, &'ll llvm::Type)> { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> Option<(&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType)> { let (pos, _, ty) = self.params.get_full(¶m)?; let elem = NUM_CONST_FIELDS + pos as u32; - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); Some((ptr, ty)) } pub unsafe fn nth_param_ptr( &self, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let ty = self.params.get_index(pos as usize).unwrap().1; let elem = NUM_CONST_FIELDS + pos; - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); (ptr, ty) } @@ -369,7 +393,7 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, ) -> MemLoc<'ll> { let ty = self.params.get_index(pos as usize).unwrap().1; let elem = NUM_CONST_FIELDS + pos; @@ -380,7 +404,7 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, param: OsdiInstanceParam, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, ) -> Option> { let pos = self.params.get_index_of(¶m)? as u32; let res = self.nth_param_loc(cx, pos, ptr); @@ -390,41 +414,55 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn read_param( &self, param: OsdiInstanceParam, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> Option<&'ll llvm::Value> { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> Option<&'ll llvm_sys::LLVMValue> { let (ptr, ty) = self.param_ptr(param, ptr, llbuilder)?; - let val = LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED); + let val = &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ); Some(val) } pub unsafe fn store_nth_param( &self, param_id: u32, - ptr: &'ll llvm::Value, - val: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + val: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let (ptr, _) = self.nth_param_ptr(param_id, ptr, llbuilder); - LLVMBuildStore(llbuilder, val, ptr) + &*LLVMBuildStore( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(val).as_ptr(), + NonNull::from(ptr).as_ptr(), + ) } pub unsafe fn read_nth_param( &self, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let (ptr, ty) = self.nth_param_ptr(pos, ptr, llbuilder); - LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED) + &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ) } // pub unsafe fn opvar_ptr( // &self, // var: VarId, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, - // ) -> Option<(&'ll llvm::Value, &'ll llvm::Type)> { + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, + // ) -> Option<(&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType)> { // let (pos, _, ty) = self.opvars.get_full(&var)?; // let elem = NUM_CONST_FIELDS + self.params.len() as u32 + pos as u32; // let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); @@ -435,7 +473,7 @@ impl<'ll> OsdiInstanceData<'ll> { &self, node: SimUnknown, reactive: bool, - target_data: &TargetData, + target_data: &LLVMTargetDataRef, ) -> Option { let residual = &self.residual[node]; let slot = if reactive { &residual.react } else { &residual.resist }; @@ -444,7 +482,9 @@ impl<'ll> OsdiInstanceData<'ll> { + self.cache_slots.len() as u32 + u32::from(slot.expand()?); - let off = unsafe { LLVMOffsetOfElement(target_data, self.ty, elem) } as u32; + let off = + unsafe { LLVMOffsetOfElement(*target_data, NonNull::from(self.ty).as_ptr(), elem) } + as u32; Some(off) } @@ -452,24 +492,32 @@ impl<'ll> OsdiInstanceData<'ll> { &self, node: SimUnknown, reactive: bool, - target_data: &TargetData, + target_data: &LLVMTargetDataRef, ) -> Option { let residual = &self.residual[node]; let residual = if reactive { &residual.react_lim_rhs } else { &residual.resist_lim_rhs }; let slot = residual.expand()?; let elem = self.eval_output_slot_elem(slot); - let off = unsafe { LLVMOffsetOfElement(target_data, self.ty, elem) } as u32; + let off = + unsafe { LLVMOffsetOfElement(*target_data, NonNull::from(self.ty).as_ptr(), elem) } + as u32; Some(off) } unsafe fn eval_output_slot_ptr( &self, - llbuilder: &llvm::Builder<'ll>, - ptr: &'ll llvm::Value, + llbuilder: &llvm_sys::LLVMBuilder, + ptr: &'ll llvm_sys::LLVMValue, slot: EvalOutputSlot, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let elem = self.eval_output_slot_elem(slot); - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); let ty = self.eval_outputs.get_index(slot).unwrap().1; (ptr, ty) } @@ -483,18 +531,23 @@ impl<'ll> OsdiInstanceData<'ll> { unsafe fn load_eval_output_slot( &self, - llbuilder: &llvm::Builder<'ll>, - ptr: &'ll llvm::Value, + llbuilder: &llvm_sys::LLVMBuilder, + ptr: &'ll llvm_sys::LLVMValue, slot: EvalOutputSlot, - ) -> &'ll llvm::Value { + ) -> &'ll llvm_sys::LLVMValue { let (ptr, ty) = self.eval_output_slot_ptr(llbuilder, ptr, slot); - LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED) + &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ) } pub unsafe fn store_eval_output_slot( &self, slot: EvalOutputSlot, - inst_ptr: &'ll llvm::Value, + inst_ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, ) { let val = *self.eval_outputs.get_index(slot).unwrap().0; @@ -506,7 +559,7 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn store_eval_output( &self, output: EvalOutput, - inst_ptr: &'ll llvm::Value, + inst_ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, ) { if let EvalOutput::Calculated(slot) = output { @@ -518,9 +571,9 @@ impl<'ll> OsdiInstanceData<'ll> { // &self, // cx: &CodegenCx<'_, 'll>, // param: OsdiInstanceParam, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, - // ) -> Option<(&'ll llvm::Value, &'ll llvm::Value)> { + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, + // ) -> Option<(&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMValue)> { // let pos = self.params.get_index_of(¶m)?; // Some(self.nth_param_given_pointer_and_mask(cx, pos as u32, ptr, llbuilder)) // } @@ -529,9 +582,9 @@ impl<'ll> OsdiInstanceData<'ll> { // &self, // cx: &CodegenCx<'_, 'll>, // pos: u32, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, - // ) -> (&'ll llvm::Value, &'ll llvm::Value) { + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, + // ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMValue) { // let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, PARAM_GIVEN, UNNAMED); // bitfield::word_ptr_and_mask(cx, pos, arr_ptr, self.param_given, llbuilder) // } @@ -540,10 +593,16 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, PARAM_GIVEN, UNNAMED); + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + PARAM_GIVEN, + UNNAMED, + ); bitfield::is_set(cx, pos, arr_ptr, self.param_given, llbuilder) } @@ -551,9 +610,9 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, param: OsdiInstanceParam, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> Option<&'ll llvm::Value> { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> Option<&'ll llvm_sys::LLVMValue> { let pos = self.params.get_index_of(¶m)?; let res = self.is_nth_param_given(cx, pos as u32, ptr, llbuilder); Some(res) @@ -563,10 +622,16 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, ) { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, PARAM_GIVEN, UNNAMED); + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + PARAM_GIVEN, + UNNAMED, + ); bitfield::set_bit(cx, pos, arr_ptr, self.param_given, llbuilder) } @@ -574,8 +639,8 @@ impl<'ll> OsdiInstanceData<'ll> { // &self, // cx: &CodegenCx<'_, 'll>, // param: OsdiInstanceParam, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, // ) -> bool { // if let Some(pos) = self.params.get_index_of(¶m) { // self.set_nth_param_given(cx, pos as u32, ptr, llbuilder); @@ -584,56 +649,110 @@ impl<'ll> OsdiInstanceData<'ll> { // false // } // } - pub unsafe fn read_node_off( &self, cx: &CodegenCx<'_, 'll>, node: SimUnknown, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, NODE_MAPPING, UNNAMED); - let zero = cx.const_int(0); - let node = cx.const_unsigned_int(node.into()); - let ptr = - LLVMBuildGEP2(llbuilder, self.node_mapping, ptr, [zero, node].as_ptr(), 2, UNNAMED); - LLVMBuildLoad2(llbuilder, cx.ty_int(), ptr, UNNAMED) + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { + let builder_ptr = NonNull::from(llbuilder).as_ptr(); + let ty_ptr = NonNull::from(self.ty).as_ptr(); + let ptr_value = NonNull::from(ptr).as_ptr(); + + // First GEP for accessing the NODE_MAPPING field + let ptr = LLVMBuildStructGEP2(builder_ptr, ty_ptr, ptr_value, NODE_MAPPING, UNNAMED); + + // Preparing indices for the next GEP + let zero = cx.const_int(0) as *const llvm_sys::LLVMValue as *mut _; + let node_val = cx.const_unsigned_int(node.into()) as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [zero, node_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + // Apply GEP2 for node mapping + let ptr = LLVMBuildGEP2( + builder_ptr, + NonNull::from(self.node_mapping).as_ptr(), + ptr, + gep_ptr, + 2, + UNNAMED, + ); + + // Load the integer value from the final pointer + &*LLVMBuildLoad2(builder_ptr, NonNull::from(cx.ty_int()).as_ptr(), ptr, UNNAMED) } pub unsafe fn read_state_idx( &self, cx: &CodegenCx<'_, 'll>, idx: LimitState, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, STATE_IDX, UNNAMED); - let zero = cx.const_int(0); - let state = cx.const_unsigned_int(idx.into()); - let ptr = LLVMBuildGEP2(llbuilder, self.state_idx, ptr, [zero, state].as_ptr(), 2, UNNAMED); - LLVMBuildLoad2(llbuilder, cx.ty_int(), ptr, UNNAMED) + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { + let builder_ptr = NonNull::from(llbuilder).as_ptr(); + let ty_ptr = NonNull::from(self.ty).as_ptr(); + let ptr_value = NonNull::from(ptr).as_ptr(); + + // First GEP for accessing the STATE_IDX field + let ptr = LLVMBuildStructGEP2(builder_ptr, ty_ptr, ptr_value, STATE_IDX, UNNAMED); + + // Preparing indices for the next GEP + let zero = cx.const_int(0) as *const llvm_sys::LLVMValue as *mut _; + let state = cx.const_unsigned_int(idx.into()) as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [zero, state]; + let gep_ptr = gep_indices.as_mut_ptr(); + + // Apply GEP2 for state index + let ptr = LLVMBuildGEP2( + builder_ptr, + NonNull::from(self.state_idx).as_ptr(), + ptr, + gep_ptr, + 2, + UNNAMED, + ); + + // Load the integer value from the final pointer + &*LLVMBuildLoad2(builder_ptr, NonNull::from(cx.ty_int()).as_ptr(), ptr, UNNAMED) } pub unsafe fn read_node_voltage( &self, cx: &CodegenCx<'_, 'll>, node: SimUnknown, - ptr: &'ll llvm::Value, - prev_result: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + prev_result: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let off = self.read_node_off(cx, node, ptr, llbuilder); - let ptr = LLVMBuildGEP2(llbuilder, cx.ty_double(), prev_result, [off].as_ptr(), 1, UNNAMED); - LLVMBuildLoad2(llbuilder, cx.ty_double(), ptr, UNNAMED) + let off_val = off as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 1] = [off_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + let ptr = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + NonNull::from(prev_result).as_ptr(), + gep_ptr, + 1, + UNNAMED, + ); + &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + ptr, + UNNAMED, + ) } pub unsafe fn read_residual( &self, node: SimUnknown, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, reactive: bool, - ) -> Option<&'ll llvm::Value> { + ) -> Option<&'ll llvm_sys::LLVMValue> { let residual = &self.residual[node]; let residual = if reactive { &residual.react } else { &residual.resist }; let val = self.load_eval_output_slot(llbuilder, ptr, residual.expand()?); @@ -643,7 +762,7 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn store_lim_rhs( &self, node: SimUnknown, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, reactive: bool, ) -> bool { @@ -660,10 +779,10 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn read_lim_rhs( &self, node: SimUnknown, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, reactive: bool, - ) -> Option<&'ll llvm::Value> { + ) -> Option<&'ll llvm_sys::LLVMValue> { let residual = &self.residual[node]; let lim_rhs = if reactive { &residual.react_lim_rhs } else { &residual.resist_lim_rhs }; let val = self.load_eval_output_slot(llbuilder, ptr, lim_rhs.expand()?); @@ -673,7 +792,7 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn store_residual( &self, node: SimUnknown, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, reactive: bool, ) -> bool { @@ -692,28 +811,57 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, node: SimUnknown, - ptr: &'ll llvm::Value, - dst: &'ll llvm::Value, - contrib: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + dst: &'ll llvm_sys::LLVMValue, + contrib: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, negate: bool, ) { let off = self.read_node_off(cx, node, ptr, llbuilder); - let dst = LLVMBuildGEP2(llbuilder, cx.ty_double(), dst, [off].as_ptr(), 1, UNNAMED); - let old = LLVMBuildLoad2(llbuilder, cx.ty_double(), dst, UNNAMED); + let off_val = off as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 1] = [off_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + let dst = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + NonNull::from(dst).as_ptr(), + gep_ptr, + 1, + UNNAMED, + ); + let old = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + dst, + UNNAMED, + ); let val = if negate { - LLVMBuildFSub(llbuilder, old, contrib, UNNAMED) + LLVMBuildFSub( + NonNull::from(llbuilder).as_ptr(), + old, + NonNull::from(contrib).as_ptr(), + UNNAMED, + ) } else { - LLVMBuildFAdd(llbuilder, old, contrib, UNNAMED) + LLVMBuildFAdd( + NonNull::from(llbuilder).as_ptr(), + old, + NonNull::from(contrib).as_ptr(), + UNNAMED, + ) }; - LLVMSetFastMath(val); - LLVMBuildStore(llbuilder, val, dst); + + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + //LLVMSetFastMath(val); + LLVMBuildStore(NonNull::from(llbuilder).as_ptr(), val, dst); } pub unsafe fn store_jacobian( &self, entry: MatrixEntryId, - inst_ptr: &'ll llvm::Value, + inst_ptr: &'ll llvm_sys::LLVMValue, builder: &mir_llvm::Builder<'_, '_, 'll>, reactive: bool, ) { @@ -729,17 +877,24 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, entry: MatrixEntryId, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, reactive: bool, has_offset: bool, - offset: &'ll llvm::Value, - val: &'ll llvm::Value, + offset: &'ll llvm_sys::LLVMValue, + val: &'ll llvm_sys::LLVMValue, ) { // Field number within instance structure let field = if reactive { JACOBIAN_PTR_REACT } else { JACOBIAN_PTR_RESIST }; + // Get pointer to array of double* pointers - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, field, UNNAMED); + let ptr = LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + field, + UNNAMED, + ); let zero = cx.const_int(0); // Get entry index let entry = if reactive { @@ -754,21 +909,60 @@ impl<'ll> OsdiInstanceData<'ll> { // Prepare type of Jacobian entry pointers array let ty = if reactive { self.jacobian_ptr_react } else { self.jacobian_ptr }; // Create pointer to array entry with index entry - let ptr = LLVMBuildGEP2(llbuilder, ty, ptr, [zero, entry].as_ptr(), 2, UNNAMED); + let zero_val = zero as *const llvm_sys::LLVMValue as *mut _; + let entry_val = entry as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [zero_val, entry_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + let ptr = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + ptr, + gep_ptr, + 2, + UNNAMED, + ); // Load value from destination pointed to by ptr (get pointer to Jacobian entry destination) - let mut dst = LLVMBuildLoad2(llbuilder, cx.ty_ptr(), ptr, UNNAMED); + let mut dst = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_ptr()).as_ptr(), + ptr, + UNNAMED, + ); // Add offset to destination if has_offset { - dst = LLVMBuildGEP2(llbuilder, cx.ty_double(), dst, [offset].as_ptr(), 1, UNNAMED); + let offset_val = offset as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 1] = [offset_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + dst = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + dst, + gep_ptr, + 1, + UNNAMED, + ); } // Load value from where the Jacobian entry should be added (pointed to by dst) - let old = LLVMBuildLoad2(llbuilder, cx.ty_double(), dst, UNNAMED); + let old = LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + dst, + UNNAMED, + ); // Add value to old - let val = LLVMBuildFAdd(llbuilder, old, val, UNNAMED); + let val = LLVMBuildFAdd( + NonNull::from(llbuilder).as_ptr(), + old, + NonNull::from(val).as_ptr(), + UNNAMED, + ); // Set fast math flags on result - LLVMSetFastMath(val); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); // Store value where dst pointer points to - LLVMBuildStore(llbuilder, val, dst); + LLVMBuildStore(NonNull::from(llbuilder).as_ptr(), val, dst); } // Writes Jacobian contribution to corresponding slot in array of doubles @@ -776,19 +970,32 @@ impl<'ll> OsdiInstanceData<'ll> { &self, cx: &CodegenCx<'_, 'll>, entry: u32, - ty: &'ll llvm::Type, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - val: &'ll llvm::Value, + ty: &'ll llvm_sys::LLVMType, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + val: &'ll llvm_sys::LLVMValue, ) { let zero = cx.const_int(0); // Convert to LLVM u32 let entry = cx.const_unsigned_int(entry); // Create pointer to array entry with index entry - let ptr = LLVMBuildGEP2(llbuilder, ty, ptr, [zero, entry].as_ptr(), 2, UNNAMED); + let zero_val = zero as *const llvm_sys::LLVMValue as *mut _; + let entry_val = entry as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [zero_val, entry_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + + let ptr = LLVMBuildGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + gep_ptr, + 2, + UNNAMED, + ); + // Store value where dst pointer points to - LLVMBuildStore(llbuilder, val, ptr); + LLVMBuildStore(NonNull::from(llbuilder).as_ptr(), NonNull::from(val).as_ptr(), ptr); } pub fn cache_slot_elem(&self, slot: CacheSlot) -> u32 { @@ -797,12 +1004,20 @@ impl<'ll> OsdiInstanceData<'ll> { fn cache_slot_ptr( &self, - llbuilder: &llvm::Builder<'ll>, + llbuilder: &llvm_sys::LLVMBuilder, slot: CacheSlot, - ptr: &'ll llvm::Value, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { + ptr: &'ll llvm_sys::LLVMValue, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let elem = self.cache_slot_elem(slot); - let ptr = unsafe { LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED) }; + let ptr = unsafe { + &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ) + }; let ty = self.cache_slots[slot]; (ptr, ty) } @@ -810,19 +1025,24 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn load_cache_slot( &self, module: &OsdiModule, - llbuilder: &llvm::Builder<'ll>, + llbuilder: &llvm_sys::LLVMBuilder, slot: CacheSlot, - ptr: &'ll llvm::Value, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { let (ptr, ty) = self.cache_slot_ptr(llbuilder, slot, ptr); - let mut val = LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED); + let mut val = &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ); if module.init.cache_slots[slot] == hir::Type::Bool { - val = LLVMBuildICmp( - llbuilder, - IntPredicate::IntNE, - val, - LLVMConstInt(ty, 0, llvm::False), + val = &*LLVMBuildICmp( + NonNull::from(llbuilder).as_ptr(), + LLVMIntPredicate::LLVMIntNE, + NonNull::from(val).as_ptr(), + LLVMConstInt(NonNull::from(ty).as_ptr(), 0, 0), UNNAMED, ); } @@ -833,50 +1053,82 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn store_cache_slot( &self, module: &OsdiModule, - llbuilder: &llvm::Builder<'ll>, + llbuilder: &llvm_sys::LLVMBuilder, slot: CacheSlot, - ptr: &'ll llvm::Value, - mut val: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, + mut val: &'ll llvm_sys::LLVMValue, ) { let (ptr, ty) = self.cache_slot_ptr(llbuilder, slot, ptr); if module.init.cache_slots[slot] == hir::Type::Bool { - val = LLVMBuildIntCast2(llbuilder, val, ty, llvm::False, UNNAMED); + val = &*LLVMBuildIntCast2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(val).as_ptr(), + NonNull::from(ty).as_ptr(), + 0, + UNNAMED, + ); } - LLVMBuildStore(llbuilder, val, ptr); + LLVMBuildStore( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(val).as_ptr(), + NonNull::from(ptr).as_ptr(), + ); } - pub unsafe fn store_is_collapsible( &self, cx: &CodegenCx<'_, 'll>, - llbuilder: &llvm::Builder<'ll>, - ptr: &'ll llvm::Value, - idx: &'ll llvm::Value, + llbuilder: &llvm_sys::LLVMBuilder, + ptr: &'ll llvm_sys::LLVMValue, + idx: &'ll llvm_sys::LLVMValue, ) { - let mut ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, COLLAPSED, UNNAMED); + let builder_ptr = NonNull::from(llbuilder).as_ptr(); + let ty_ptr = NonNull::from(self.ty).as_ptr(); + + // Create GEP for the struct field + let mut ptr = LLVMBuildStructGEP2( + builder_ptr, + ty_ptr, + NonNull::from(ptr).as_ptr(), + COLLAPSED, + UNNAMED, + ); + + // Stable storage for GEP indices + let idx_0: llvm_sys::prelude::LLVMValueRef = + cx.const_unsigned_int(0) as *const llvm_sys::LLVMValue as *mut _; + let idx_1: llvm_sys::prelude::LLVMValueRef = idx as *const llvm_sys::LLVMValue as *mut _; + + // Pointers array for GEP indices + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 2] = [idx_0, idx_1]; + let gep_ptr = gep_indices.as_mut_ptr(); + + // Apply GEP2 for collapsed field ptr = LLVMBuildGEP2( - llbuilder, - self.collapsed, + builder_ptr, + NonNull::from(self.collapsed).as_ptr(), ptr, - [cx.const_unsigned_int(0), idx].as_ptr(), + gep_ptr, 2, UNNAMED, ); - LLVMBuildStore(llbuilder, cx.const_c_bool(true), ptr); + + // Final store operation + LLVMBuildStore(builder_ptr, NonNull::from(cx.const_c_bool(true)).as_ptr(), ptr); } pub unsafe fn temperature_loc( &self, cx: &CodegenCx<'_, 'll>, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, ) -> MemLoc<'ll> { MemLoc::struct_gep(ptr, self.ty, cx.ty_double(), TEMPERATURE, cx) } pub unsafe fn store_temperature( &self, - builder: &mir_llvm::Builder<'_, '_, 'll>, - ptr: &'ll llvm::Value, - val: &'ll llvm::Value, + builder: &mut mir_llvm::Builder<'_, '_, 'll>, + ptr: &'ll llvm_sys::LLVMValue, + val: &'ll llvm_sys::LLVMValue, ) { let ptr = builder.struct_gep(self.ty, ptr, TEMPERATURE); builder.store(ptr, val) @@ -884,19 +1136,22 @@ impl<'ll> OsdiInstanceData<'ll> { pub unsafe fn load_connected_ports( &self, - builder: &mir_llvm::Builder<'_, '_, 'll>, - ptr: &'ll llvm::Value, - ) -> &'ll llvm::Value { + builder: &mut mir_llvm::Builder<'_, '_, 'll>, + ptr: &'ll llvm_sys::LLVMValue, + ) -> &'ll llvm_sys::LLVMValue { let ptr = builder.struct_gep(self.ty, ptr, CONNECTED); builder.load(builder.cx.ty_int(), ptr) } pub unsafe fn store_connected_ports( &self, - builder: &mir_llvm::Builder<'_, '_, 'll>, - ptr: &'ll llvm::Value, - val: &'ll llvm::Value, + builder: &mut mir_llvm::Builder<'_, '_, 'll>, + ptr: &'ll llvm_sys::LLVMValue, + val: &'ll llvm_sys::LLVMValue, ) { + /*let builder_mut: &mut _ = unsafe { + &mut *(builder as *const _ as *mut mir_llvm::Builder<'_, '_, 'll>) + };*/ let ptr = builder.struct_gep(self.ty, ptr, CONNECTED); builder.store(ptr, val) } @@ -906,10 +1161,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { pub unsafe fn load_eval_output( &self, output: EvalOutput, - inst_ptr: &'ll llvm::Value, - model_ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + inst_ptr: &'ll llvm_sys::LLVMValue, + model_ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { inst_data, model_data, cx, module, .. } = self; let (ptr, ty) = match output { EvalOutput::Calculated(slot) => { @@ -928,10 +1183,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { model_data.param_ptr(param, model_ptr, llbuilder).unwrap() }), ParamKind::Temperature => ( - LLVMBuildStructGEP2( - llbuilder, - cx.ty_double(), - inst_ptr, + &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + NonNull::from(inst_ptr).as_ptr(), TEMPERATURE, UNNAMED, ), @@ -958,17 +1213,22 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { EvalOutput::Cache(slot) => inst_data.cache_slot_ptr(llbuilder, slot, inst_ptr), }; - LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED) + &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ) } pub unsafe fn load_jacobian_entry( &self, entry: MatrixEntryId, - inst_ptr: &'ll llvm::Value, - model_ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + inst_ptr: &'ll llvm_sys::LLVMValue, + model_ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, reactive: bool, - ) -> Option<&'ll llvm::Value> { + ) -> Option<&'ll llvm_sys::LLVMValue> { let entry = &self.inst_data.jacobian[entry]; let entry = if reactive { entry.react } else { entry.resist }; let val = self.load_eval_output(entry?, inst_ptr, model_ptr, llbuilder); @@ -978,10 +1238,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { pub unsafe fn nth_opvar_ptr( &self, pos: u32, - inst_ptr: &'ll llvm::Value, - model_ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { + inst_ptr: &'ll llvm_sys::LLVMValue, + model_ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let OsdiCompilationUnit { inst_data, model_data, cx, module, .. } = self; match *inst_data.opvars.get_index(pos as usize).unwrap().1 { EvalOutput::Calculated(slot) => { @@ -989,7 +1249,11 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } EvalOutput::Const(val, slot) => { let (ptr, ty) = inst_data.eval_output_slot_ptr(llbuilder, inst_ptr, slot.unwrap()); - LLVMBuildStore(llbuilder, cx.const_val(&val), ptr); + LLVMBuildStore( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.const_val(&val)).as_ptr(), + NonNull::from(ptr).as_ptr(), + ); (ptr, ty) } EvalOutput::Param(param) => { @@ -1002,10 +1266,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { model_data.param_ptr(param, model_ptr, llbuilder).unwrap() }), ParamKind::Temperature => ( - LLVMBuildStructGEP2( - llbuilder, - cx.ty_double(), - inst_ptr, + &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(cx.ty_double()).as_ptr(), + NonNull::from(inst_ptr).as_ptr(), TEMPERATURE, UNNAMED, ), diff --git a/openvaf/osdi/src/lib.rs b/openvaf/osdi/src/lib.rs index 3b18cce..8e2a34f 100644 --- a/openvaf/osdi/src/lib.rs +++ b/openvaf/osdi/src/lib.rs @@ -1,3 +1,4 @@ +use core::ptr::NonNull; use std::ffi::CString; use base_n::CASE_INSENSITIVE; @@ -5,7 +6,8 @@ use camino::{Utf8Path, Utf8PathBuf}; use hir::{CompilationDB, ParamSysFun, Type}; use hir_lower::{CallBackKind, HirInterner, ParamKind}; use lasso::Rodeo; -use llvm::{LLVMABISizeOfType, LLVMDisposeTargetData, OptLevel}; +use llvm_sys::target::{LLVMABISizeOfType, LLVMDisposeTargetData}; +use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mir_llvm::{CodegenCx, LLVMBackend}; use salsa::ParallelDatabase; use sim_back::{CompiledModule, ModuleInfo}; @@ -31,6 +33,23 @@ mod setup; const OSDI_VERSION: (u32, u32) = (0, 4); +use std::sync::Once; + +use llvm_sys::target::{LLVM_InitializeNativeAsmPrinter, LLVM_InitializeNativeTarget}; + +static LLVM_INIT: Once = Once::new(); + +fn initialize_llvm() { + LLVM_INIT.call_once(|| unsafe { + if LLVM_InitializeNativeTarget() != 0 { + panic!("Failed to initialize native target"); + } + if LLVM_InitializeNativeAsmPrinter() != 0 { + panic!("Failed to initialize native ASM printer"); + } + }); +} + pub fn compile( db: &CompilationDB, modules: &[ModuleInfo], @@ -38,8 +57,9 @@ pub fn compile( target: &Target, back: &LLVMBackend, emit: bool, - opt_lvl: OptLevel, + opt_lvl: LLVMCodeGenOptLevel, ) -> Vec { + initialize_llvm(); let mut literals = Rodeo::new(); let mut lim_table = TiSet::default(); let modules: Vec<_> = modules @@ -66,7 +86,7 @@ pub fn compile( let target_data = unsafe { let src = CString::new(target.data_layout.clone()).unwrap(); - llvm::LLVMCreateTargetData(src.as_ptr()) + &*llvm_sys::target::LLVMCreateTargetData(src.as_ptr()) }; let modules: Vec<_> = modules @@ -85,7 +105,7 @@ pub fn compile( rayon_core::scope(|scope| { let db = db; let literals_ = &literals; - let target_data_ = &target_data; + let target_data_ = target_data; let paths = &paths; for (i, module) in modules.iter().enumerate() { @@ -94,7 +114,7 @@ pub fn compile( let access = format!("access_{}", &module.sym); let llmod = unsafe { back.new_module(&access, opt_lvl).unwrap() }; let cx = new_codegen(back, &llmod, literals_); - let tys = OsdiTys::new(&cx, target_data_); + let tys = OsdiTys::new(&cx, NonNull::from(target_data_).as_ptr()); let cguint = OsdiCompilationUnit::new(&_db, module, &cx, &tys, false); cguint.access_function(); @@ -112,7 +132,7 @@ pub fn compile( let name = format!("setup_model_{}", &module.sym); let llmod = unsafe { back.new_module(&name, opt_lvl).unwrap() }; let cx = new_codegen(back, &llmod, literals_); - let tys = OsdiTys::new(&cx, target_data_); + let tys = OsdiTys::new(&cx, NonNull::from(target_data_).as_ptr()); let cguint = OsdiCompilationUnit::new(&_db, module, &cx, &tys, false); cguint.setup_model(); @@ -130,10 +150,13 @@ pub fn compile( let name = format!("setup_instance_{}", &module.sym); let llmod = unsafe { back.new_module(&name, opt_lvl).unwrap() }; let cx = new_codegen(back, &llmod, literals_); - let tys = OsdiTys::new(&cx, target_data_); + let tys = OsdiTys::new(&cx, NonNull::from(target_data_).as_ptr()); let mut cguint = OsdiCompilationUnit::new(&_db, module, &cx, &tys, false); cguint.setup_instance(); + //let _ir = llmod.to_str(); + //println!("llmod: {}", _ir); + debug_assert!(llmod.verify_and_print()); if emit { @@ -148,7 +171,7 @@ pub fn compile( let access = format!("eval_{}", &module.sym); let llmod = unsafe { back.new_module(&access, opt_lvl).unwrap() }; let cx = new_codegen(back, &llmod, literals_); - let tys = OsdiTys::new(&cx, target_data_); + let tys = OsdiTys::new(&cx, NonNull::from(target_data_).as_ptr()); let cguint = OsdiCompilationUnit::new(&_db, module, &cx, &tys, true); // println!("{:?}", module.eval); @@ -166,13 +189,13 @@ pub fn compile( let llmod = unsafe { back.new_module(&name, opt_lvl).unwrap() }; let cx = new_codegen(back, &llmod, &literals); - let tys = OsdiTys::new(&cx, target_data); + let tys = OsdiTys::new(&cx, NonNull::from(target_data).as_ptr()); let descriptors: Vec<_> = modules .iter() .map(|module| { let cguint = OsdiCompilationUnit::new(&db, module, &cx, &tys, false); - let descriptor = cguint.descriptor(target_data, &db); + let descriptor = cguint.descriptor(&NonNull::from(target_data).as_ptr(), &db); descriptor.to_ll_val(&cx, &tys) }) .collect(); @@ -199,7 +222,10 @@ pub fn compile( let descr_size: u32; unsafe { - descr_size = LLVMABISizeOfType(target_data, tys.osdi_descriptor) as u32; + descr_size = LLVMABISizeOfType( + NonNull::from(target_data).as_ptr(), + NonNull::from(tys.osdi_descriptor).as_ptr(), + ) as u32; } cx.export_val("OSDI_DESCRIPTOR_SIZE", cx.ty_int(), cx.const_unsigned_int(descr_size), true); @@ -219,10 +245,22 @@ pub fn compile( cx.get_declared_value("osdi_log").expect("symbol osdi_log missing from std lib"); let val = cx.const_null_ptr(); unsafe { - llvm::LLVMSetInitializer(osdi_log, val); - llvm::LLVMSetLinkage(osdi_log, llvm::Linkage::ExternalLinkage); - llvm::LLVMSetUnnamedAddress(osdi_log, llvm::UnnamedAddr::No); - llvm::LLVMSetDLLStorageClass(osdi_log, llvm::DLLStorageClass::Export); + llvm_sys::core::LLVMSetInitializer( + NonNull::from(osdi_log).as_ptr(), + NonNull::from(val).as_ptr(), + ); + llvm_sys::core::LLVMSetLinkage( + NonNull::from(osdi_log).as_ptr(), + llvm_sys::LLVMLinkage::LLVMExternalLinkage, + ); + llvm_sys::core::LLVMSetUnnamedAddress( + NonNull::from(osdi_log).as_ptr(), + llvm_sys::LLVMUnnamedAddr::LLVMNoUnnamedAddr, + ); + llvm_sys::core::LLVMSetDLLStorageClass( + NonNull::from(osdi_log).as_ptr(), + llvm_sys::LLVMDLLStorageClass::LLVMDLLExportStorageClass, + ); } debug_assert!(llmod.verify_and_print()); @@ -236,7 +274,7 @@ pub fn compile( }); paths.push(main_file); - unsafe { LLVMDisposeTargetData(target_data) }; + unsafe { LLVMDisposeTargetData(NonNull::from(target_data).as_ptr()) }; paths } @@ -299,7 +337,7 @@ fn ty_len(ty: &Type) -> Option { } } -fn lltype<'ll>(ty: &Type, cx: &CodegenCx<'_, 'll>) -> &'ll llvm::Type { +fn lltype<'ll>(ty: &Type, cx: &CodegenCx<'_, 'll>) -> &'ll llvm_sys::LLVMType { let llty = match ty.base_type() { Type::Real => cx.ty_double(), Type::Integer => cx.ty_int(), diff --git a/openvaf/osdi/src/load.rs b/openvaf/osdi/src/load.rs index cabc333..a2c2e5a 100644 --- a/openvaf/osdi/src/load.rs +++ b/openvaf/osdi/src/load.rs @@ -1,15 +1,17 @@ -use llvm::{ +use core::ffi::c_uint; +use std::ptr::NonNull; + +use llvm_sys::core::{ LLVMAppendBasicBlockInContext, LLVMBuildCall2, LLVMBuildFAdd, LLVMBuildFDiv, LLVMBuildFMul, LLVMBuildFSub, LLVMBuildGEP2, LLVMBuildRetVoid, LLVMBuildStore, LLVMCreateBuilderInContext, - LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, LLVMSetFastMath, - LLVMSetPartialFastMath, UNNAMED, + LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, }; +use mir_llvm::UNNAMED; use sim_back::dae::NoiseSourceKind; use stdx::iter::zip; use typed_index_collections::TiVec; use crate::compilation_unit::OsdiCompilationUnit; - #[derive(Debug, Clone, Copy)] pub enum JacobianLoadType { Tran, @@ -40,7 +42,7 @@ impl JacobianLoadType { } impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { - pub fn load_noise(&self) -> &'ll llvm::Value { + pub fn load_noise(&self) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { cx, module, .. } = self; let void_ptr = cx.ty_ptr(); let f64_ptr_ty = cx.ty_ptr(); @@ -49,55 +51,109 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); - let inst = LLVMGetParam(llfunc, 0); - let model = LLVMGetParam(llfunc, 1); - let freq = LLVMGetParam(llfunc, 2); - let dst = LLVMGetParam(llfunc, 3); + let inst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let model = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); + let freq = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); + let dst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3); for (i, (src, eval_outputs)) in zip(&module.dae_system.noise_sources, &self.inst_data.noise).enumerate() { - let fac = self.load_eval_output(eval_outputs.factor, inst, model, llbuilder); + let fac = self.load_eval_output(eval_outputs.factor, &*inst, &*model, &*llbuilder); let mut pwr = match src.kind { NoiseSourceKind::WhiteNoise { .. } => { - self.load_eval_output(eval_outputs.args[0], inst, model, llbuilder) + self.load_eval_output(eval_outputs.args[0], &*inst, &*model, &*llbuilder) } NoiseSourceKind::FlickerNoise { .. } => { - let mut pwr = - self.load_eval_output(eval_outputs.args[0], inst, model, llbuilder); - let exp = - self.load_eval_output(eval_outputs.args[1], inst, model, llbuilder); + let mut pwr = self.load_eval_output( + eval_outputs.args[0], + &*inst, + &*model, + &*llbuilder, + ); + let exp = &*self.load_eval_output( + eval_outputs.args[1], + &*inst, + &*model, + &*llbuilder, + ); let (ty, fun) = self .cx .intrinsic("llvm.pow.f64") .unwrap_or_else(|| unreachable!("intrinsic {} not found", name)); - let freq_exp = - LLVMBuildCall2(llbuilder, ty, fun, [freq, exp].as_ptr(), 2, UNNAMED); - LLVMSetPartialFastMath(freq_exp); - pwr = LLVMBuildFDiv(llbuilder, pwr, freq_exp, UNNAMED); - LLVMSetFastMath(pwr); + + let freq_val = freq as *const llvm_sys::LLVMValue as *mut _; + let exp_val = &*exp as *const llvm_sys::LLVMValue as *mut _; + let mut call_args: [llvm_sys::prelude::LLVMValueRef; 2] = + [freq_val, exp_val]; + let args_ptr = call_args.as_mut_ptr(); + + let freq_exp = LLVMBuildCall2( + llbuilder, + NonNull::from(ty).as_ptr(), + NonNull::from(fun).as_ptr(), + args_ptr, + 2, + UNNAMED, + ); + let fast_math_flags: c_uint = 0x01 | 0x02 | 0x10; // Reassoc | Reciprocal | Contract + llvm_sys::core::LLVMSetFastMathFlags(freq_exp, fast_math_flags); + + pwr = &*LLVMBuildFDiv( + llbuilder, + NonNull::from(pwr).as_ptr(), + freq_exp, + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags( + NonNull::from(pwr).as_ptr(), + fast_math_flags, + ); + pwr } NoiseSourceKind::NoiseTable { .. } => unimplemented!("noise tables"), }; + // Multiply with squared factor because factor is in terms of signal, but // we are computing the power, which is scaled by factor**2. - pwr = LLVMBuildFMul(llbuilder, pwr, fac, UNNAMED); - LLVMSetFastMath(pwr); - pwr = LLVMBuildFMul(llbuilder, pwr, fac, UNNAMED); - LLVMSetFastMath(pwr); + pwr = &*LLVMBuildFMul( + llbuilder, + NonNull::from(pwr).as_ptr(), + NonNull::from(fac).as_ptr(), + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(NonNull::from(pwr).as_ptr(), fast_math_flags); + pwr = &*LLVMBuildFMul( + llbuilder, + NonNull::from(pwr).as_ptr(), + NonNull::from(fac).as_ptr(), + UNNAMED, + ); + llvm_sys::core::LLVMSetFastMathFlags(NonNull::from(pwr).as_ptr(), fast_math_flags); + let index_val = + cx.const_unsigned_int(i as u32) as *const llvm_sys::LLVMValue as *mut _; + let mut gep_indices: [llvm_sys::prelude::LLVMValueRef; 1] = [index_val]; + let gep_ptr = gep_indices.as_mut_ptr(); + let dst = LLVMBuildGEP2( llbuilder, - cx.ty_double(), + NonNull::from(cx.ty_double()).as_ptr(), dst, - [cx.const_unsigned_int(i as u32)].as_ptr(), + gep_ptr, 1, UNNAMED, ); - LLVMBuildStore(llbuilder, pwr, dst); + LLVMBuildStore(llbuilder, NonNull::from(pwr).as_ptr(), dst); } // TODO noise @@ -108,7 +164,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { llfunc } - pub fn load_residual(&self, reactive: bool) -> &'ll llvm::Value { + pub fn load_residual(&self, reactive: bool) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { inst_data, cx, module, .. } = self; let ptr_ty = cx.ty_ptr(); let fun_ty = cx.ty_func(&[ptr_ty, ptr_ty, ptr_ty], cx.ty_void()); @@ -117,18 +173,22 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let dst = LLVMGetParam(llfunc, 2); + let inst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let dst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); for node in module.dae_system.unknowns.indices() { - if let Some(contrib) = inst_data.read_residual(node, inst, llbuilder, reactive) { - inst_data.store_contrib(cx, node, inst, dst, contrib, llbuilder, false); + if let Some(contrib) = inst_data.read_residual(node, inst, &*llbuilder, reactive) { + inst_data.store_contrib(cx, node, inst, dst, contrib, &*llbuilder, false); } } @@ -139,7 +199,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { llfunc } - pub fn load_lim_rhs(&self, reactive: bool) -> &'ll llvm::Value { + pub fn load_lim_rhs(&self, reactive: bool) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { inst_data, cx, module, .. } = self; let void_ptr = cx.ty_ptr(); let f64_ptr_ty = cx.ty_ptr(); @@ -149,18 +209,22 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let dst = LLVMGetParam(llfunc, 2); + let inst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let dst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); for node in module.dae_system.unknowns.indices() { - if let Some(contrib) = inst_data.read_lim_rhs(node, inst, llbuilder, reactive) { - inst_data.store_contrib(cx, node, inst, dst, contrib, llbuilder, true); + if let Some(contrib) = inst_data.read_lim_rhs(node, inst, &*llbuilder, reactive) { + inst_data.store_contrib(cx, node, inst, dst, contrib, &*llbuilder, true); } } @@ -175,12 +239,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { pub fn load_spice_rhs_( &self, tran: bool, - llbuilder: &llvm::Builder<'ll>, - inst: &'ll llvm::Value, - model: &'ll llvm::Value, - dst: &'ll llvm::Value, - prev_solve: &'ll llvm::Value, - alpha: &'ll llvm::Value, + llbuilder: &llvm_sys::LLVMBuilder, + inst: &'ll llvm_sys::LLVMValue, + model: &'ll llvm_sys::LLVMValue, + dst: &'ll llvm_sys::LLVMValue, + prev_solve: &'ll llvm_sys::LLVMValue, + alpha: &'ll llvm_sys::LLVMValue, ) { let dae_system = &self.module.dae_system; let mut node_derivatives = TiVec::from(vec![Vec::new(); dae_system.unknowns.len()]); @@ -204,12 +268,22 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let voltage = self .inst_data .read_node_voltage(self.cx, node_deriv, inst, prev_solve, llbuilder); - let val = LLVMBuildFMul(llbuilder, ddx, voltage, UNNAMED); - LLVMSetFastMath(val); + let val = LLVMBuildFMul( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ddx).as_ptr(), + NonNull::from(voltage).as_ptr(), + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + res = match res { Some(old) => { - let val = LLVMBuildFAdd(llbuilder, old, val, UNNAMED); - LLVMSetFastMath(val); + let val = + LLVMBuildFAdd(NonNull::from(llbuilder).as_ptr(), old, val, UNNAMED); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + Some(val) } None => Some(val), @@ -220,30 +294,42 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { if !tran { if let Some(contrib) = inst_data.read_residual(node, inst, llbuilder, false) { let val = LLVMBuildFSub( - llbuilder, - res.unwrap_or_else(|| cx.const_real(0.0)), - contrib, + NonNull::from(llbuilder).as_ptr(), + res.unwrap_or_else(|| NonNull::from(cx.const_real(0.0)).as_ptr()), + NonNull::from(contrib).as_ptr(), UNNAMED, ); - LLVMSetFastMath(val); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); res = Some(val); } } if let Some(mut res) = res { if let Some(lim_rhs) = inst_data.read_lim_rhs(node, inst, llbuilder, tran) { - res = LLVMBuildFAdd(llbuilder, res, lim_rhs, UNNAMED); + res = LLVMBuildFAdd( + NonNull::from(llbuilder).as_ptr(), + res, + NonNull::from(lim_rhs).as_ptr(), + UNNAMED, + ); } if tran { - res = LLVMBuildFMul(llbuilder, res, alpha, UNNAMED); - LLVMSetFastMath(res); + res = LLVMBuildFMul( + NonNull::from(llbuilder).as_ptr(), + res, + NonNull::from(alpha).as_ptr(), + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(res, fast_math_flags); } - inst_data.store_contrib(cx, node, inst, dst, res, llbuilder, false); + inst_data.store_contrib(cx, node, inst, dst, &*res, llbuilder, false); } } } } - pub fn load_spice_rhs(&self, tran: bool) -> &'ll llvm::Value { + pub fn load_spice_rhs(&self, tran: bool) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { cx, module, .. } = self; let f64_ty = cx.ty_double(); let ptr_ty = cx.ty_ptr(); @@ -256,20 +342,25 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let model = LLVMGetParam(llfunc, 1); - let dst = LLVMGetParam(llfunc, 2); - let prev_solve = LLVMGetParam(llfunc, 3); - let alpha = if tran { LLVMGetParam(llfunc, 4) } else { prev_solve }; - - self.load_spice_rhs_(false, llbuilder, inst, model, dst, prev_solve, alpha); + let inst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let model = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); + let dst = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); + let prev_solve = &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3); + let alpha = + if tran { &*LLVMGetParam(NonNull::from(llfunc).as_ptr(), 4) } else { prev_solve }; + + self.load_spice_rhs_(false, &*llbuilder, inst, model, dst, prev_solve, alpha); if tran { - self.load_spice_rhs_(true, llbuilder, inst, model, dst, prev_solve, alpha); + self.load_spice_rhs_(true, &*llbuilder, inst, model, dst, prev_solve, alpha); } LLVMBuildRetVoid(llbuilder); @@ -279,7 +370,11 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { llfunc } - pub fn load_jacobian(&self, kind: JacobianLoadType, with_offset: bool) -> &'ll llvm::Value { + pub fn load_jacobian( + &self, + kind: JacobianLoadType, + with_offset: bool, + ) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { cx, module, .. } = *self; let fun_ty = if !with_offset { if kind.read_reactive() { @@ -299,22 +394,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(&name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // Get params - let inst = LLVMGetParam(llfunc, 0); - let model = LLVMGetParam(llfunc, 1); + let inst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let model = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); let alpha = if !with_offset && kind.read_reactive() { // Reactive part - LLVMGetParam(llfunc, 2) + LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2) } else { // Some dummy inst }; let offset = if with_offset { - LLVMGetParam(llfunc, 2) + LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2) } else { // Some dummy inst @@ -323,23 +422,39 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { for entry in module.dae_system.jacobian.keys() { let mut res = None; if kind.read_resistive() { - res = self.load_jacobian_entry(entry, inst, model, llbuilder, false); + res = self.load_jacobian_entry(entry, &*inst, &*model, &*llbuilder, false); } if kind.read_reactive() { if let Some(mut val) = - self.load_jacobian_entry(entry, inst, model, llbuilder, true) + self.load_jacobian_entry(entry, &*inst, &*model, &*llbuilder, true) { // with_offset assumes alpha=1 if !with_offset { - val = LLVMBuildFMul(llbuilder, val, alpha, UNNAMED); - LLVMSetFastMath(val); + val = &*LLVMBuildFMul( + llbuilder, + NonNull::from(val).as_ptr(), + alpha, + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags( + NonNull::from(val).as_ptr(), + fast_math_flags, + ); } val = match res { Some(resist) => { - let val = LLVMBuildFAdd(llbuilder, resist, val, UNNAMED); - LLVMSetFastMath(val); - val + let val = LLVMBuildFAdd( + llbuilder, + NonNull::from(resist).as_ptr(), + NonNull::from(val).as_ptr(), + UNNAMED, + ); + let fast_math_flags: c_uint = 0x1F; // This represents all flags set + llvm_sys::core::LLVMSetFastMathFlags(val, fast_math_flags); + + &*val } None => val, }; @@ -351,11 +466,11 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { self.inst_data.store_jacobian_contrib( self.cx, entry, - inst, - llbuilder, + &*inst, + &*llbuilder, kind.dst_reactive(), with_offset, - offset, + &*offset, res, ); } @@ -372,7 +487,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { // Writes Jacobian entries into a double array of size num_jacobian_entries // If a particular entry is not present, nothing is loaded. // Array of doubles need not be zeroed before calling this function. - pub fn write_jacobian_array(&self, kind: JacobianLoadType) -> &'ll llvm::Value { + pub fn write_jacobian_array(&self, kind: JacobianLoadType) -> &'ll llvm_sys::LLVMValue { let OsdiCompilationUnit { cx, module, .. } = *self; let args = [cx.ty_ptr(), cx.ty_ptr(), cx.ty_ptr()]; let fun_ty = cx.ty_func(&args, cx.ty_void()); @@ -380,14 +495,18 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llfunc = cx.declare_int_c_fn(name, fun_ty); unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let model = LLVMGetParam(llfunc, 1); - let dest_array = LLVMGetParam(llfunc, 2); + let inst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let model = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); + let dest_array = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2); // Destination array type let len = { @@ -404,18 +523,24 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let res = { if kind.read_resistive() { // Load resistive Jacobian value from instance structure - self.load_jacobian_entry(entry, inst, model, llbuilder, false) + self.load_jacobian_entry(entry, &*inst, &*model, &*llbuilder, false) } else { // Load reactive Jacobian value from instance structure - self.load_jacobian_entry(entry, inst, model, llbuilder, true) + self.load_jacobian_entry(entry, &*inst, &*model, &*llbuilder, true) } }; // Do we have any result in res if let Some(res) = res { // Store it in array pointed to by ptr - self.inst_data - .write_jacobian_contrib(self.cx, pos, dest_ty, dest_array, llbuilder, res); + self.inst_data.write_jacobian_contrib( + self.cx, + pos, + dest_ty, + NonNull::new_unchecked(dest_array).as_ref(), + NonNull::new_unchecked(llbuilder).as_ref(), + res, + ); pos = pos + 1; } } diff --git a/openvaf/osdi/src/metadata.rs b/openvaf/osdi/src/metadata.rs index ab9a07c..c1c45e9 100644 --- a/openvaf/osdi/src/metadata.rs +++ b/openvaf/osdi/src/metadata.rs @@ -1,9 +1,10 @@ +use core::ptr::NonNull; use std::iter::once; use hir::{CompilationDB, ParamSysFun, Type}; use hir_lower::CurrentKind; use lasso::{Rodeo, Spur}; -use llvm::{LLVMABISizeOfType, LLVMOffsetOfElement, TargetData}; +use llvm_sys::target::{LLVMABISizeOfType, LLVMOffsetOfElement, LLVMTargetDataRef}; use mir::{ValueDef, F_ZERO}; use mir_llvm::CodegenCx; use sim_back::dae::MatrixEntry; @@ -33,7 +34,11 @@ pub struct OsdiLimFunction { } impl OsdiLimFunction { - pub fn to_ll_val<'ll>(self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { osdi_0_4::OsdiLimFunction { name: ctx.literals.resolve(&self.name).to_owned(), num_args: self.num_args, @@ -135,7 +140,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { inst_params.chain(model_params).chain(opvars).collect() } - pub fn nodes(&self, target_data: &TargetData, db: &CompilationDB) -> Vec { + pub fn nodes(&self, target_data: &LLVMTargetDataRef, db: &CompilationDB) -> Vec { let OsdiCompilationUnit { inst_data, module, .. } = self; module .dae_system @@ -181,10 +186,15 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } } - pub fn jacobian_entries(&self, target_data: &TargetData) -> Vec { + pub fn jacobian_entries(&self, target_data: &LLVMTargetDataRef) -> Vec { let OsdiCompilationUnit { inst_data, module, .. } = self; - let mut jacobian_ptr_react_offset = - unsafe { LLVMOffsetOfElement(target_data, inst_data.ty, JACOBIAN_PTR_REACT) } as u32; + let mut jacobian_ptr_react_offset = unsafe { + LLVMOffsetOfElement( + *target_data, + NonNull::from(inst_data.ty).as_ptr(), + JACOBIAN_PTR_REACT, + ) + } as u32; module .dae_system @@ -242,7 +252,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { pub fn descriptor( &self, - target_data: &llvm::TargetData, + target_data: &llvm_sys::target::LLVMTargetDataRef, db: &CompilationDB, ) -> OsdiDescriptor<'ll> { let collapsible = self.collapsible(); @@ -250,20 +260,32 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let OsdiCompilationUnit { ref inst_data, ref model_data, module, cx, .. } = *self; unsafe { - let node_mapping_offset = - LLVMOffsetOfElement(target_data, inst_data.ty, NODE_MAPPING) as u32; - let jacobian_ptr_resist_offset = - LLVMOffsetOfElement(target_data, inst_data.ty, JACOBIAN_PTR_RESIST) as u32; - - let collapsed_offset = LLVMOffsetOfElement(target_data, inst_data.ty, COLLAPSED) as u32; + let node_mapping_offset = LLVMOffsetOfElement( + *target_data, + NonNull::from(inst_data.ty).as_ptr(), + NODE_MAPPING, + ) as u32; + let jacobian_ptr_resist_offset = LLVMOffsetOfElement( + *target_data, + NonNull::from(inst_data.ty).as_ptr(), + JACOBIAN_PTR_RESIST, + ) as u32; + + let collapsed_offset = + LLVMOffsetOfElement(*target_data, NonNull::from(inst_data.ty).as_ptr(), COLLAPSED) + as u32; let bound_step_offset = inst_data.bound_step_elem().map_or(u32::MAX, |elem| { - LLVMOffsetOfElement(target_data, inst_data.ty, elem) as u32 + LLVMOffsetOfElement(*target_data, NonNull::from(inst_data.ty).as_ptr(), elem) as u32 }); - let state_idx_off = LLVMOffsetOfElement(target_data, inst_data.ty, STATE_IDX) as u32; + let state_idx_off = + LLVMOffsetOfElement(*target_data, NonNull::from(inst_data.ty).as_ptr(), STATE_IDX) + as u32; - let instance_size = LLVMABISizeOfType(target_data, inst_data.ty) as u32; - let model_size = LLVMABISizeOfType(target_data, model_data.ty) as u32; + let instance_size = + LLVMABISizeOfType(*target_data, NonNull::from(inst_data.ty).as_ptr()) as u32; + let model_size = + LLVMABISizeOfType(*target_data, NonNull::from(model_data.ty).as_ptr()) as u32; let noise_sources: Vec<_> = module .dae_system diff --git a/openvaf/osdi/src/metadata/osdi_0_4.rs b/openvaf/osdi/src/metadata/osdi_0_4.rs index e1ad241..d74bfa1 100644 --- a/openvaf/osdi/src/metadata/osdi_0_4.rs +++ b/openvaf/osdi/src/metadata/osdi_0_4.rs @@ -76,10 +76,14 @@ pub const INIT_ERR_OUT_OF_BOUNDS: u32 = 1; pub struct OsdiLimFunction<'ll> { pub name: String, pub num_args: u32, - pub func_ptr: &'ll llvm::Value, + pub func_ptr: &'ll llvm_sys::LLVMValue, } impl<'ll> OsdiLimFunction<'ll> { - pub fn to_ll_val(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let fields = [ ctx.const_str_uninterned(&self.name), ctx.const_unsigned_int(self.num_args), @@ -124,14 +128,20 @@ impl OsdiTyBuilder<'_, '_, '_> { fn osdi_init_error_payload(&mut self) { let ctx = self.ctx; unsafe { - let align = [llvm::LLVMABIAlignmentOfType(self.target_data, ctx.ty_int())] - .into_iter() - .max() - .unwrap(); - let mut size = [llvm::LLVMABISizeOfType(self.target_data, ctx.ty_int())] - .into_iter() - .max() - .unwrap() as u32; + let align = [llvm_sys::target::LLVMABIAlignmentOfType( + self.target_data.clone(), + core::ptr::NonNull::from(ctx.ty_int()).as_ptr(), + )] + .into_iter() + .max() + .unwrap(); + let mut size = [llvm_sys::target::LLVMABISizeOfType( + self.target_data.clone(), + core::ptr::NonNull::from(ctx.ty_int()).as_ptr(), + )] + .into_iter() + .max() + .unwrap() as u32; size = (size + align - 1) / align; let elem = ctx.ty_aint(align * 8); let ty = ctx.ty_array(elem, size); @@ -160,7 +170,11 @@ pub struct OsdiNodePair { pub node_2: u32, } impl OsdiNodePair { - pub fn to_ll_val<'ll>(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let fields = [ctx.const_unsigned_int(self.node_1), ctx.const_unsigned_int(self.node_2)]; let ty = tys.osdi_node_pair; ctx.const_struct(ty, &fields) @@ -180,7 +194,11 @@ pub struct OsdiJacobianEntry { pub flags: u32, } impl OsdiJacobianEntry { - pub fn to_ll_val<'ll>(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let fields = [ self.nodes.to_ll_val(ctx, tys), ctx.const_unsigned_int(self.react_ptr_off), @@ -209,7 +227,11 @@ pub struct OsdiNode { pub is_flow: bool, } impl OsdiNode { - pub fn to_ll_val<'ll>(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let fields = [ ctx.const_str_uninterned(&self.name), ctx.const_str_uninterned(&self.units), @@ -250,7 +272,11 @@ pub struct OsdiParamOpvar { pub len: u32, } impl OsdiParamOpvar { - pub fn to_ll_val<'ll>(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let arr_0: Vec<_> = self.name.iter().map(|it| ctx.const_str_uninterned(it)).collect(); let fields = [ ctx.const_arr_ptr(ctx.ty_ptr(), &arr_0), @@ -278,7 +304,11 @@ pub struct OsdiNoiseSource { pub nodes: OsdiNodePair, } impl OsdiNoiseSource { - pub fn to_ll_val<'ll>(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val<'ll>( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let fields = [ctx.const_str_uninterned(&self.name), self.nodes.to_ll_val(ctx, tys)]; let ty = tys.osdi_noise_source; ctx.const_struct(ty, &fields) @@ -315,33 +345,37 @@ pub struct OsdiDescriptor<'ll> { pub bound_step_offset: u32, pub instance_size: u32, pub model_size: u32, - pub access: &'ll llvm::Value, - pub setup_model: &'ll llvm::Value, - pub setup_instance: &'ll llvm::Value, - pub eval: &'ll llvm::Value, - pub load_noise: &'ll llvm::Value, - pub load_residual_resist: &'ll llvm::Value, - pub load_residual_react: &'ll llvm::Value, - pub load_limit_rhs_resist: &'ll llvm::Value, - pub load_limit_rhs_react: &'ll llvm::Value, - pub load_spice_rhs_dc: &'ll llvm::Value, - pub load_spice_rhs_tran: &'ll llvm::Value, - pub load_jacobian_resist: &'ll llvm::Value, - pub load_jacobian_react: &'ll llvm::Value, - pub load_jacobian_tran: &'ll llvm::Value, - pub given_flag_model: &'ll llvm::Value, - pub given_flag_instance: &'ll llvm::Value, + pub access: &'ll llvm_sys::LLVMValue, + pub setup_model: &'ll llvm_sys::LLVMValue, + pub setup_instance: &'ll llvm_sys::LLVMValue, + pub eval: &'ll llvm_sys::LLVMValue, + pub load_noise: &'ll llvm_sys::LLVMValue, + pub load_residual_resist: &'ll llvm_sys::LLVMValue, + pub load_residual_react: &'ll llvm_sys::LLVMValue, + pub load_limit_rhs_resist: &'ll llvm_sys::LLVMValue, + pub load_limit_rhs_react: &'ll llvm_sys::LLVMValue, + pub load_spice_rhs_dc: &'ll llvm_sys::LLVMValue, + pub load_spice_rhs_tran: &'ll llvm_sys::LLVMValue, + pub load_jacobian_resist: &'ll llvm_sys::LLVMValue, + pub load_jacobian_react: &'ll llvm_sys::LLVMValue, + pub load_jacobian_tran: &'ll llvm_sys::LLVMValue, + pub given_flag_model: &'ll llvm_sys::LLVMValue, + pub given_flag_instance: &'ll llvm_sys::LLVMValue, pub num_resistive_jacobian_entries: u32, pub num_reactive_jacobian_entries: u32, - pub write_jacobian_array_resist: &'ll llvm::Value, - pub write_jacobian_array_react: &'ll llvm::Value, + pub write_jacobian_array_resist: &'ll llvm_sys::LLVMValue, + pub write_jacobian_array_react: &'ll llvm_sys::LLVMValue, pub num_inputs: u32, pub inputs: Vec, - pub load_jacobian_with_offset_resist: &'ll llvm::Value, - pub load_jacobian_with_offset_react: &'ll llvm::Value, + pub load_jacobian_with_offset_resist: &'ll llvm_sys::LLVMValue, + pub load_jacobian_with_offset_react: &'ll llvm_sys::LLVMValue, } impl<'ll> OsdiDescriptor<'ll> { - pub fn to_ll_val(&self, ctx: &CodegenCx<'_, 'll>, tys: &'ll OsdiTys) -> &'ll llvm::Value { + pub fn to_ll_val( + &self, + ctx: &CodegenCx<'_, 'll>, + tys: &'ll OsdiTys, + ) -> &'ll llvm_sys::LLVMValue { let arr_3: Vec<_> = self.nodes.iter().map(|it| it.to_ll_val(ctx, tys)).collect(); let arr_5: Vec<_> = self.jacobian_entries.iter().map(|it| it.to_ll_val(ctx, tys)).collect(); let arr_7: Vec<_> = self.collapsible.iter().map(|it| it.to_ll_val(ctx, tys)).collect(); @@ -457,21 +491,21 @@ impl OsdiTyBuilder<'_, '_, '_> { } #[derive(Clone)] pub struct OsdiTys<'ll> { - pub osdi_lim_function: &'ll llvm::Type, - pub osdi_sim_paras: &'ll llvm::Type, - pub osdi_sim_info: &'ll llvm::Type, - pub osdi_init_error_payload: &'ll llvm::Type, - pub osdi_init_error: &'ll llvm::Type, - pub osdi_init_info: &'ll llvm::Type, - pub osdi_node_pair: &'ll llvm::Type, - pub osdi_jacobian_entry: &'ll llvm::Type, - pub osdi_node: &'ll llvm::Type, - pub osdi_param_opvar: &'ll llvm::Type, - pub osdi_noise_source: &'ll llvm::Type, - pub osdi_descriptor: &'ll llvm::Type, + pub osdi_lim_function: &'ll llvm_sys::LLVMType, + pub osdi_sim_paras: &'ll llvm_sys::LLVMType, + pub osdi_sim_info: &'ll llvm_sys::LLVMType, + pub osdi_init_error_payload: &'ll llvm_sys::LLVMType, + pub osdi_init_error: &'ll llvm_sys::LLVMType, + pub osdi_init_info: &'ll llvm_sys::LLVMType, + pub osdi_node_pair: &'ll llvm_sys::LLVMType, + pub osdi_jacobian_entry: &'ll llvm_sys::LLVMType, + pub osdi_node: &'ll llvm_sys::LLVMType, + pub osdi_param_opvar: &'ll llvm_sys::LLVMType, + pub osdi_noise_source: &'ll llvm_sys::LLVMType, + pub osdi_descriptor: &'ll llvm_sys::LLVMType, } impl<'ll> OsdiTys<'ll> { - pub fn new(ctx: &CodegenCx<'_, 'll>, target_data: &llvm::TargetData) -> Self { + pub fn new(ctx: &CodegenCx<'_, 'll>, target_data: llvm_sys::target::LLVMTargetDataRef) -> Self { let mut builder = OsdiTyBuilder { ctx, target_data, @@ -505,19 +539,19 @@ impl<'ll> OsdiTys<'ll> { } struct OsdiTyBuilder<'a, 'b, 'll> { ctx: &'a CodegenCx<'b, 'll>, - target_data: &'a llvm::TargetData, - osdi_lim_function: Option<&'ll llvm::Type>, - osdi_sim_paras: Option<&'ll llvm::Type>, - osdi_sim_info: Option<&'ll llvm::Type>, - osdi_init_error_payload: Option<&'ll llvm::Type>, - osdi_init_error: Option<&'ll llvm::Type>, - osdi_init_info: Option<&'ll llvm::Type>, - osdi_node_pair: Option<&'ll llvm::Type>, - osdi_jacobian_entry: Option<&'ll llvm::Type>, - osdi_node: Option<&'ll llvm::Type>, - osdi_param_opvar: Option<&'ll llvm::Type>, - osdi_noise_source: Option<&'ll llvm::Type>, - osdi_descriptor: Option<&'ll llvm::Type>, + target_data: llvm_sys::target::LLVMTargetDataRef, + osdi_lim_function: Option<&'ll llvm_sys::LLVMType>, + osdi_sim_paras: Option<&'ll llvm_sys::LLVMType>, + osdi_sim_info: Option<&'ll llvm_sys::LLVMType>, + osdi_init_error_payload: Option<&'ll llvm_sys::LLVMType>, + osdi_init_error: Option<&'ll llvm_sys::LLVMType>, + osdi_init_info: Option<&'ll llvm_sys::LLVMType>, + osdi_node_pair: Option<&'ll llvm_sys::LLVMType>, + osdi_jacobian_entry: Option<&'ll llvm_sys::LLVMType>, + osdi_node: Option<&'ll llvm_sys::LLVMType>, + osdi_param_opvar: Option<&'ll llvm_sys::LLVMType>, + osdi_noise_source: Option<&'ll llvm_sys::LLVMType>, + osdi_descriptor: Option<&'ll llvm_sys::LLVMType>, } impl<'ll> OsdiTyBuilder<'_, '_, 'll> { fn finish(self) -> OsdiTys<'ll> { diff --git a/openvaf/osdi/src/model_data.rs b/openvaf/osdi/src/model_data.rs index 893f641..0d2bc2f 100644 --- a/openvaf/osdi/src/model_data.rs +++ b/openvaf/osdi/src/model_data.rs @@ -1,8 +1,11 @@ +use core::ptr::NonNull; + use ahash::RandomState; use hir::{CompilationDB, Parameter}; use indexmap::IndexMap; -use llvm::{LLVMBuildLoad2, LLVMBuildStore, LLVMBuildStructGEP2, Value, UNNAMED}; -use mir_llvm::{CodegenCx, MemLoc}; +use llvm_sys::core::{LLVMBuildLoad2, LLVMBuildStore, LLVMBuildStructGEP2}; +use llvm_sys::LLVMValue as Value; +use mir_llvm::{CodegenCx, MemLoc, UNNAMED}; use crate::compilation_unit::OsdiModule; use crate::inst_data::{OsdiInstanceData, OsdiInstanceParam}; @@ -11,9 +14,9 @@ use crate::{bitfield, lltype}; const NUM_CONST_FIELDS: u32 = 1; pub struct OsdiModelData<'ll> { - pub param_given: &'ll llvm::Type, - pub params: IndexMap, - pub ty: &'ll llvm::Type, + pub param_given: &'ll llvm_sys::LLVMType, + pub params: IndexMap, + pub ty: &'ll llvm_sys::LLVMType, } impl<'ll> OsdiModelData<'ll> { @@ -54,7 +57,7 @@ impl<'ll> OsdiModelData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, ) -> MemLoc<'ll> { let ty = self.params.get_index(pos as usize).unwrap().1; let elem = NUM_CONST_FIELDS + pos; @@ -67,7 +70,7 @@ impl<'ll> OsdiModelData<'ll> { &self, cx: &CodegenCx<'_, 'll>, param: Parameter, - ptr: &'ll llvm::Value, + ptr: &'ll llvm_sys::LLVMValue, ) -> Option> { let pos = self.params.get_index_of(¶m)? as u32; let res = self.nth_param_loc(cx, pos, ptr); @@ -77,12 +80,18 @@ impl<'ll> OsdiModelData<'ll> { pub unsafe fn param_ptr( &self, param: Parameter, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> Option<(&'ll llvm::Value, &'ll llvm::Type)> { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> Option<(&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType)> { let (pos, _, ty) = self.params.get_full(¶m)?; let elem = NUM_CONST_FIELDS + pos as u32; - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); Some((ptr, ty)) } @@ -90,15 +99,21 @@ impl<'ll> OsdiModelData<'ll> { pub unsafe fn nth_param_ptr( &self, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { // unwrap() returns a tuple holding parameter and type, .1 selects type (ref to ref) + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let ty = self.params.get_index(pos as usize).unwrap().1; // index of element, skip NUM_CONST_FIELDS let elem = NUM_CONST_FIELDS + pos; // retrieve pointer to parameter storage within model data structure pointed to by ptr - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); (ptr, ty) } @@ -106,24 +121,30 @@ impl<'ll> OsdiModelData<'ll> { &self, inst_data: &OsdiInstanceData<'ll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { // get the type, but this time from inst_data because pos is the instance parameter index + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let ty = inst_data.params.get_index(pos as usize).unwrap().1; // index of element, skip NUM_CONST_FIELDS, then skip model parameter fields let elem = NUM_CONST_FIELDS + self.params.len() as u32 + pos; // retrieve pointer to parameter storage within model data structure pointed to by ptr - let ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, elem, UNNAMED); + let ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + elem, + UNNAMED, + ); (ptr, ty) } // pub unsafe fn read_param( // &self, // param: ParamId, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, - // ) -> Option<&'ll llvm::Value> { + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, + // ) -> Option<&'ll llvm_sys::LLVMValue> { // let (ptr, ty) = self.param_ptr(param, ptr, llbuilder)?; // let val = LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED); // Some(val) @@ -133,19 +154,23 @@ impl<'ll> OsdiModelData<'ll> { &self, param: u32, ptr: &'ll Value, - val: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + val: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, ) { let (ptr, _) = self.nth_param_ptr(param, ptr, llbuilder); - LLVMBuildStore(llbuilder, val, ptr); + LLVMBuildStore( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(val).as_ptr(), + NonNull::from(ptr).as_ptr(), + ); } // pub unsafe fn read_nth_param( // &self, // param: u32, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, - // ) -> &'ll llvm::Value { + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, + // ) -> &'ll llvm_sys::LLVMValue { // let (ptr, ty) = self.nth_param_ptr(param, ptr, llbuilder); // LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED) // } @@ -154,21 +179,32 @@ impl<'ll> OsdiModelData<'ll> { &self, inst_data: &OsdiInstanceData<'ll>, param: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let (ptr, ty) = self.nth_inst_param_ptr(inst_data, param, ptr, llbuilder); - LLVMBuildLoad2(llbuilder, ty, ptr, UNNAMED) + &*LLVMBuildLoad2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + UNNAMED, + ) } pub unsafe fn is_nth_param_given( &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, 0, UNNAMED); + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + 0, + UNNAMED, + ); bitfield::is_set(cx, pos, arr_ptr, self.param_given, llbuilder) } @@ -176,10 +212,16 @@ impl<'ll> OsdiModelData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, 0, UNNAMED); + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + 0, + UNNAMED, + ); bitfield::is_set(cx, pos + self.params.len() as u32, arr_ptr, self.param_given, llbuilder) } @@ -188,9 +230,9 @@ impl<'ll> OsdiModelData<'ll> { inst_data: &OsdiInstanceData<'ll>, cx: &CodegenCx<'_, 'll>, param: OsdiInstanceParam, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> &'ll llvm::Value { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> &'ll llvm_sys::LLVMValue { let pos = inst_data.params.get_index_of(¶m).unwrap(); self.is_nth_inst_param_given(cx, pos as u32, ptr, llbuilder) } @@ -198,9 +240,9 @@ impl<'ll> OsdiModelData<'ll> { &self, cx: &CodegenCx<'_, 'll>, param: Parameter, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, - ) -> Option<&'ll llvm::Value> { + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, + ) -> Option<&'ll llvm_sys::LLVMValue> { let pos = self.params.get_index_of(¶m)?; let res = self.is_nth_param_given(cx, pos as u32, ptr, llbuilder); Some(res) @@ -210,20 +252,32 @@ impl<'ll> OsdiModelData<'ll> { &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, ) { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, 0, UNNAMED); + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + 0, + UNNAMED, + ); bitfield::set_bit(cx, pos + self.params.len() as u32, arr_ptr, self.param_given, llbuilder) } pub unsafe fn set_nth_param_given( &self, cx: &CodegenCx<'_, 'll>, pos: u32, - ptr: &'ll llvm::Value, - llbuilder: &llvm::Builder<'ll>, + ptr: &'ll llvm_sys::LLVMValue, + llbuilder: &llvm_sys::LLVMBuilder, ) { - let arr_ptr = LLVMBuildStructGEP2(llbuilder, self.ty, ptr, 0, UNNAMED); + let arr_ptr = &*LLVMBuildStructGEP2( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(self.ty).as_ptr(), + NonNull::from(ptr).as_ptr(), + 0, + UNNAMED, + ); bitfield::set_bit(cx, pos, arr_ptr, self.param_given, llbuilder) } @@ -231,8 +285,8 @@ impl<'ll> OsdiModelData<'ll> { // &self, // cx: &CodegenCx<'_, 'll>, // param: ParamId, - // ptr: &'ll llvm::Value, - // llbuilder: &llvm::Builder<'ll>, + // ptr: &'ll llvm_sys::LLVMValue, + // llbuilder: &llvm_sys::LLVMBuilder, // ) -> bool { // if let Some(pos) = self.params.get_index_of(¶m) { // self.set_nth_param_given(cx, pos as u32, ptr, llbuilder); diff --git a/openvaf/osdi/src/setup.rs b/openvaf/osdi/src/setup.rs index 2491803..7797355 100644 --- a/openvaf/osdi/src/setup.rs +++ b/openvaf/osdi/src/setup.rs @@ -1,34 +1,41 @@ +use core::ptr::NonNull; + use hir_lower::{CallBackKind, ParamInfoKind, ParamKind, PlaceKind}; -use llvm::IntPredicate::IntSLT; -use llvm::{ +use llvm_sys::core::{ LLVMAppendBasicBlockInContext, LLVMBuildBr, LLVMBuildCondBr, LLVMBuildRetVoid, LLVMCreateBuilderInContext, LLVMDisposeBuilder, LLVMGetParam, LLVMPositionBuilderAtEnd, - UNNAMED, }; +use llvm_sys::LLVMIntPredicate::LLVMIntSLT; use mir::ControlFlowGraph; -use mir_llvm::{Builder, BuilderVal, CallbackFun, CodegenCx}; +use mir_llvm::{Builder, BuilderVal, CallbackFun, CodegenCx, UNNAMED}; use sim_back::SimUnknownKind; use crate::compilation_unit::{general_callbacks, OsdiCompilationUnit}; use crate::inst_data::OsdiInstanceParam; impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { - fn mark_collapsed(&self) -> (&'ll llvm::Value, &'ll llvm::Type) { + fn mark_collapsed(&self) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let OsdiCompilationUnit { inst_data, cx, .. } = self; let fn_type = cx.ty_func(&[cx.ty_ptr(), cx.ty_int()], cx.ty_void()); let name = &format!("collapse_{}", &self.module.sym); let llfunc = cx.declare_int_c_fn(name, fn_type); + // Debug: Building constants and function unsafe { - let entry = LLVMAppendBasicBlockInContext(cx.llcx, llfunc, UNNAMED); - let llbuilder = LLVMCreateBuilderInContext(cx.llcx); + // Debug: Building constants + let entry = LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(llfunc).as_ptr(), + UNNAMED, + ); + let llbuilder = LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); LLVMPositionBuilderAtEnd(llbuilder, entry); // get params - let inst = LLVMGetParam(llfunc, 0); - let idx = LLVMGetParam(llfunc, 1); + let inst = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0); + let idx = LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1); - inst_data.store_is_collapsible(cx, llbuilder, inst, idx); + inst_data.store_is_collapsible(cx, &*llbuilder, &*inst, &*idx); LLVMBuildRetVoid(llbuilder); LLVMDisposeBuilder(llbuilder); @@ -37,7 +44,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { (llfunc, fn_type) } - fn invalid_param_err(cx: &CodegenCx<'_, 'll>) -> (&'ll llvm::Type, &'ll llvm::Value) { + fn invalid_param_err( + cx: &CodegenCx<'_, 'll>, + ) -> (&'ll llvm_sys::LLVMType, &'ll llvm_sys::LLVMValue) { let val = cx .get_func_by_name("push_invalid_param_err") .expect("stdlib function push_invalid_param_err is missing"); @@ -47,7 +56,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { (ty, val) } - pub fn setup_model_prototype(&self) -> &'ll llvm::Value { + pub fn setup_model_prototype(&self) -> &'ll llvm_sys::LLVMValue { let cx = &self.cx; let name = &format!("setup_model_{}", &self.module.sym); @@ -56,7 +65,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { cx.declare_ext_fn(name, fun_ty) } - pub fn setup_model(&self) -> &'ll llvm::Value { + pub fn setup_model(&self) -> &'ll llvm_sys::LLVMValue { let llfunc = self.setup_model_prototype(); let OsdiCompilationUnit { inst_data, model_data, tys, cx, .. } = self; @@ -68,9 +77,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let mut builder = Builder::new(cx, func, llfunc); let postorder: Vec<_> = cfg.postorder(func).collect(); - let handle = unsafe { llvm::LLVMGetParam(llfunc, 0) }; - let model = unsafe { llvm::LLVMGetParam(llfunc, 1) }; - let simparam = unsafe { llvm::LLVMGetParam(llfunc, 2) }; + let handle = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0) }; + let model = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1) }; + let simparam = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2) }; builder.params = vec![BuilderVal::Undef; intern.params.len()].into(); @@ -78,12 +87,12 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let i = i as u32; let dst = intern.params.unwrap_index(&ParamKind::Param(param)); - let loc = model_data.nth_param_loc(cx, i, model); + let loc = unsafe { model_data.nth_param_loc(cx, i, &*model) }; builder.params[dst] = BuilderVal::Load(Box::new(loc)); let dst = intern.params.unwrap_index(&ParamKind::ParamGiven { param }); let is_given = - unsafe { model_data.is_nth_param_given(cx, i, model, builder.llbuilder) }; + unsafe { model_data.is_nth_param_given(cx, i, &*model, builder.llbuilder) }; builder.params[dst] = BuilderVal::Eager(is_given); } @@ -91,10 +100,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let i = i as u32; let is_given = - unsafe { model_data.is_nth_inst_param_given(cx, i, model, builder.llbuilder) }; + unsafe { model_data.is_nth_inst_param_given(cx, i, &*model, builder.llbuilder) }; let val = - unsafe { model_data.read_nth_inst_param(inst_data, i, model, builder.llbuilder) }; + unsafe { model_data.read_nth_inst_param(inst_data, i, &*model, builder.llbuilder) }; match *param { OsdiInstanceParam::Builtin(builtin) => { @@ -106,7 +115,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } } OsdiInstanceParam::User(param) => { + // Debug: Processing OsdiInstanceParam::User let dst = intern.params.unwrap_index(&ParamKind::Param(param)); + // Debug: Destination index for user param: dst builder.params[dst] = BuilderVal::Eager(val); let dst = intern.params.unwrap_index(&ParamKind::ParamGiven { param }); builder.params[dst] = BuilderVal::Eager(is_given); @@ -114,7 +125,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } } - let res = unsafe { llvm::LLVMGetParam(llfunc, 3) }; + let res = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3) }; let err_cap = unsafe { builder.alloca(cx.ty_int()) }; @@ -133,11 +144,15 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } let invalid_param_err = Self::invalid_param_err(cx); + // Debug: invalid_param_err retrieved let ret_flags = unsafe { builder.alloca(cx.ty_int()) }; unsafe { builder.store(ret_flags, cx.const_int(0)) }; - builder.callbacks = general_callbacks(intern, &mut builder, ret_flags, handle, simparam); + builder.callbacks = + general_callbacks(intern, &mut builder, ret_flags, unsafe { &*handle }, unsafe { + &*simparam + }); for (call_id, call) in intern.callbacks.iter_enumerated() { if let CallBackKind::ParamInfo(ParamInfoKind::Invalid, param) = call { if !self.module.info.params[param].is_instance { @@ -178,17 +193,19 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { builder.select_bb_before_terminator(bb); unsafe { let val = builder.values[val].get(&builder); - model_data.store_nth_param(i as u32, model, val, builder.llbuilder); + model_data.store_nth_param(i as u32, &*model, val, builder.llbuilder); } } builder.select_bb(exit_bb); + // Debug: Selected exit_bb unsafe { builder.ret_void() } + // Debug: Function returns void llfunc } - pub fn setup_instance_prototype(&self) -> &'ll llvm::Value { + pub fn setup_instance_prototype(&self) -> &'ll llvm_sys::LLVMValue { let name = &format!("setup_instance_{}", &self.module.sym); let cx = &self.cx; @@ -211,51 +228,68 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { cx.declare_ext_fn(name, fun_ty) } - pub fn setup_instance(&mut self) -> &'ll llvm::Value { + pub fn setup_instance(&mut self) -> &'ll llvm_sys::LLVMValue { + // Debug: Entering setup_instance let mark_collapsed = self.mark_collapsed(); + // Debug: mark_collapsed output: (llfunc, fn_type) let llfunc = self.setup_instance_prototype(); + // Debug: setup_instance_prototype output: llfunc let OsdiCompilationUnit { inst_data, model_data, tys, cx, module, .. } = self; let func = &module.init.func; let intern = &module.init.intern; let mut builder = Builder::new(cx, func, llfunc); - - let handle = unsafe { llvm::LLVMGetParam(llfunc, 0) }; - let instance = unsafe { llvm::LLVMGetParam(llfunc, 1) }; - let model = unsafe { llvm::LLVMGetParam(llfunc, 2) }; - let temperature = unsafe { llvm::LLVMGetParam(llfunc, 3) }; - let connected_terminals = unsafe { llvm::LLVMGetParam(llfunc, 4) }; - let simparam = unsafe { llvm::LLVMGetParam(llfunc, 5) }; - let res = unsafe { llvm::LLVMGetParam(llfunc, 6) }; + // Debug: Builder initialized + + let handle = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 0) }; + let instance = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 1) }; + let model = unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 2) }; + let temperature = + unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 3) }; + let connected_terminals = + unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 4) }; + let simparam = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 5) }; + let res = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfunc).as_ptr(), 6) }; + // Debug: Parameters retrieved let ret_flags = unsafe { builder.alloca(cx.ty_int()) }; unsafe { builder.store(ret_flags, cx.const_int(0)) }; + // Debug: ret_flags initialized builder.params = vec![BuilderVal::Undef; intern.params.len()].into(); let true_ = cx.const_bool(true); + // Debug: true_ constant created for (i, param) in inst_data.params.keys().enumerate() { let i = i as u32; + // Debug: Processing inst_data.params let is_inst_given = unsafe { inst_data.is_nth_param_given(cx, i, instance, builder.llbuilder) }; + // Debug: is_inst_given for param {}: is_inst_given let is_given = unsafe { let is_given_model = model_data.is_nth_inst_param_given(cx, i, model, builder.llbuilder); builder.select(is_inst_given, true_, is_given_model) }; + // Debug: is_given for param {}: is_given let inst_val = unsafe { inst_data.read_nth_param(i, instance, builder.llbuilder) }; + // Debug: inst_val for param {}: inst_val let model_val = unsafe { model_data.read_nth_inst_param(inst_data, i, model, builder.llbuilder) }; + // Debug: model_val for param {}: model_val let val = unsafe { builder.select(is_inst_given, inst_val, model_val) }; + // Debug: Selected val for param {}: val match *param { OsdiInstanceParam::Builtin(builtin) => { let default_val = builtin.default_value(); let default_val = cx.const_real(default_val); + // Debug: Processing OsdiInstanceParam::Builtin let val = unsafe { builder.select(is_given, val, default_val) }; + // Debug: Selected val for builtin param: val unsafe { inst_data.store_nth_param(i, instance, val, builder.llbuilder); } @@ -288,7 +322,7 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } if let Some(dst) = intern.params.index(&ParamKind::Temperature) { - builder.params[dst] = BuilderVal::Eager(temperature) + builder.params[dst] = BuilderVal::Eager(unsafe { &*temperature }) } for (node_id, unknown) in module.dae_system.unknowns.iter_enumerated() { @@ -301,23 +335,26 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } let id = cx.const_unsigned_int(node_id.into()); - let is_connected = unsafe { builder.int_cmp(id, connected_terminals, IntSLT) }; + let is_connected = + unsafe { builder.int_cmp(id, &*connected_terminals, LLVMIntSLT) }; builder.params[dst] = BuilderVal::Eager(is_connected) } } } // store for use in eval() function - unsafe { inst_data.store_temperature(&builder, instance, temperature) }; - unsafe { inst_data.store_connected_ports(&builder, instance, connected_terminals) }; + unsafe { inst_data.store_temperature(&mut builder, instance, &*temperature) }; + unsafe { inst_data.store_connected_ports(&mut builder, instance, &*connected_terminals) }; + // Debug: Setting up trivial callbacks let trivial_cb = cx.trivial_callbacks(&[]); + // Debug: trivial_cb initialized let err_cap = unsafe { builder.alloca(cx.ty_int()) }; - let flags = unsafe { builder.struct_gep(tys.osdi_init_info, res, 0) }; - let err_len = unsafe { builder.struct_gep(tys.osdi_init_info, res, 1) }; - let err_ptr = unsafe { builder.struct_gep(tys.osdi_init_info, res, 2) }; + let flags = unsafe { builder.struct_gep(tys.osdi_init_info, &*res, 0) }; + let err_len = unsafe { builder.struct_gep(tys.osdi_init_info, &*res, 1) }; + let err_ptr = unsafe { builder.struct_gep(tys.osdi_init_info, &*res, 2) }; let nullptr = cx.const_null_ptr(); let zero = cx.const_unsigned_int(0); @@ -330,7 +367,10 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { } let invalid_param_err = Self::invalid_param_err(cx); - builder.callbacks = general_callbacks(intern, &mut builder, ret_flags, handle, simparam); + builder.callbacks = + general_callbacks(intern, &mut builder, ret_flags, unsafe { &*handle }, unsafe { + &*simparam + }); for (call_id, call) in intern.callbacks.iter_enumerated() { let cb = match call { CallBackKind::ParamInfo(ParamInfoKind::Invalid, param) => { @@ -378,7 +418,9 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { builder.build_consts(); builder.build_func(); } + // Debug: Building function let exit_bb = func.layout.last_block().unwrap(); + // Debug: exit_bb determined // store parameters for (i, param) in inst_data.params.keys().enumerate() { @@ -408,17 +450,30 @@ impl<'ll> OsdiCompilationUnit<'_, '_, 'll> { let llcx = cx.llcx; let llbuilder = &*builder.llbuilder; unsafe { - let else_bb = LLVMAppendBasicBlockInContext(llcx, builder.fun, UNNAMED); - let then_bb = LLVMAppendBasicBlockInContext(llcx, builder.fun, UNNAMED); + let else_bb = LLVMAppendBasicBlockInContext( + NonNull::from(llcx).as_ptr(), + NonNull::from(builder.fun).as_ptr(), + UNNAMED, + ); + let then_bb = LLVMAppendBasicBlockInContext( + NonNull::from(llcx).as_ptr(), + NonNull::from(builder.fun).as_ptr(), + UNNAMED, + ); let should_collapse = builder.values[should_collapse].get(&builder); - LLVMBuildCondBr(llbuilder, should_collapse, then_bb, else_bb); - LLVMPositionBuilderAtEnd(llbuilder, then_bb); + LLVMBuildCondBr( + NonNull::from(llbuilder).as_ptr(), + NonNull::from(should_collapse).as_ptr(), + then_bb, + else_bb, + ); + LLVMPositionBuilderAtEnd(NonNull::from(llbuilder).as_ptr(), then_bb); module.node_collapse.hint(eq, None, |pair| { let idx = cx.const_unsigned_int(pair.into()); inst_data.store_is_collapsible(cx, builder.llbuilder, instance, idx); }); - LLVMBuildBr(llbuilder, else_bb); - LLVMPositionBuilderAtEnd(llbuilder, else_bb); + LLVMBuildBr(NonNull::from(llbuilder).as_ptr(), else_bb); + LLVMPositionBuilderAtEnd(NonNull::from(llbuilder).as_ptr(), else_bb); } } } diff --git a/openvaf/osdi/src/tests.rs b/openvaf/osdi/src/tests.rs index 300cf25..b500da1 100644 --- a/openvaf/osdi/src/tests.rs +++ b/openvaf/osdi/src/tests.rs @@ -1,7 +1,7 @@ use std::path::Path; use camino::Utf8Path; -use llvm::OptLevel; +use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mir_llvm::LLVMBackend; use paths::AbsPathBuf; use sim_back::CompilationDB; @@ -25,7 +25,7 @@ fn test_compile(root_file: &Path) { &target, &back, emit, - OptLevel::Aggressive, + LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive, ); } diff --git a/openvaf/osdi/tests/data_tests.rs b/openvaf/osdi/tests/data_tests.rs index a55b156..e60b08b 100644 --- a/openvaf/osdi/tests/data_tests.rs +++ b/openvaf/osdi/tests/data_tests.rs @@ -3,7 +3,7 @@ use std::path::Path; use camino::Utf8Path; use hir::diagnostics::ConsoleSink; use hir::CompilationDB; -use llvm::OptLevel; +use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mini_harness::{harness, Result}; use mir_llvm::LLVMBackend; use paths::AbsPathBuf; @@ -18,7 +18,15 @@ fn test_compile(root_file: &Path) { let target = Target::host_target().unwrap(); let back = LLVMBackend::new(&[], &target, "native".to_owned(), &[]); let emit = !stdx::IS_CI; - osdi::compile(&db, &modules, Utf8Path::new("foo.o"), &target, &back, emit, OptLevel::None); + osdi::compile( + &db, + &modules, + Utf8Path::new("foo.o"), + &target, + &back, + emit, + LLVMCodeGenOptLevel::LLVMCodeGenLevelNone, + ); } fn integration_test(dir: &Path) -> Result { diff --git a/openvaf/preprocessor/src/scoped_arc_arena.rs b/openvaf/preprocessor/src/scoped_arc_arena.rs index 1708050..3c247fe 100644 --- a/openvaf/preprocessor/src/scoped_arc_arena.rs +++ b/openvaf/preprocessor/src/scoped_arc_arena.rs @@ -41,7 +41,7 @@ impl ScopedArea { // So the UnsacfeCell is also save here let sources = &mut *self.0.get(); // check if the same data is already guarded by the arena - if !sources.iter().any(|x| x.as_ptr() == contents.as_ptr()) { + if !sources.iter().any(|x| std::ptr::addr_eq(x.as_ptr(), contents.as_ptr())) { sources.push(T::clone(&contents)) } &*contents.as_ptr() diff --git a/openvaf/sim_back/Cargo.toml b/openvaf/sim_back/Cargo.toml index e8d5945..31fc528 100644 --- a/openvaf/sim_back/Cargo.toml +++ b/openvaf/sim_back/Cargo.toml @@ -27,7 +27,7 @@ ahash = "0.8" lasso = {version = "0.7", features = ["ahash"]} indexmap = "2.0" -smol_str = {version = "0.2", default_features=false} +smol_str = {version = "0.2", default-features=false} cov-mark = { version = "1.1.0", default-features = false } mir_build = { version = "0.0.0", path = "../mir_build" } diff --git a/openvaf/syntax/Cargo.toml b/openvaf/syntax/Cargo.toml index c6dd8f8..fec7afd 100644 --- a/openvaf/syntax/Cargo.toml +++ b/openvaf/syntax/Cargo.toml @@ -25,4 +25,4 @@ tokens = {version="0.0.0", path="../tokens"} text-size = "1.1" rowan = "0.15" -smol_str = {version = "0.2", default_features=false} \ No newline at end of file +smol_str = {version = "0.2", default-features=false} \ No newline at end of file diff --git a/sourcegen/src/osdi.rs b/sourcegen/src/osdi.rs index 763ea07..965754f 100644 --- a/sourcegen/src/osdi.rs +++ b/sourcegen/src/osdi.rs @@ -312,7 +312,7 @@ struct TyInterpolater<'b, 'a> { impl ToTokens for TyInterpolater<'_, '_> { fn to_tokens(&self, tokens: &mut TokenStream) { if self.ty.func_args.is_some() || self.ty.base == BaseTy::Void { - quote!(&'ll llvm::Value).to_tokens(tokens); + quote!(&'ll llvm_sys::LLVMValue).to_tokens(tokens); return; } @@ -532,7 +532,7 @@ impl ToTokens for OsdiStructInterp<'_, '_> { } impl #lt #ident #lt{ - pub fn to_ll_val #func_lt (&self, ctx: &CodegenCx<'_,'ll>, tys: &'ll OsdiTys) -> &'ll llvm::Value{ + pub fn to_ll_val #func_lt (&self, ctx: &CodegenCx<'_,'ll>, tys: &'ll OsdiTys) -> &'ll llvm_sys::LLVMValue{ #(#field_ll_arrays)* let fields = [#(#field_ll_vals),*]; let ty = tys.#llvm_ty_ident; @@ -553,8 +553,8 @@ impl ToTokens for OsdiStructInterp<'_, '_> { fn #llvm_ty_ident(&mut self){ let ctx = self.ctx; unsafe{ - let align = [#(llvm::LLVMABIAlignmentOfType(self.target_data, #field_ll_tys)),*].into_iter().max().unwrap(); - let mut size = [#(llvm::LLVMABISizeOfType(self.target_data, #field_ll_tys2)),*].into_iter().max().unwrap() as u32; + let align = [#(llvm_sys::target::LLVMABIAlignmentOfType(self.target_data.clone(), core::ptr::NonNull::from(#field_ll_tys).as_ptr())),*].into_iter().max().unwrap(); + let mut size = [#(llvm_sys::target::LLVMABISizeOfType(self.target_data.clone(), core::ptr::NonNull::from(#field_ll_tys2).as_ptr())),*].into_iter().max().unwrap() as u32; size = (size + align - 1) / align; let elem = ctx.ty_aint(align*8); let ty = ctx.ty_array(elem, size); @@ -714,11 +714,11 @@ fn gen_llvm_tys<'a>(tys: &IndexMap<&'a str, OsdiStruct<'a>, RandomState>) -> Str #[derive(Clone)] pub struct OsdiTys<'ll>{ - #(pub #fields : &'ll llvm::Type),* + #(pub #fields : &'ll llvm_sys::LLVMType),* } impl<'ll> OsdiTys<'ll>{ - pub fn new(ctx: &CodegenCx<'_, 'll>, target_data: &llvm::TargetData) -> Self{ + pub fn new(ctx: &CodegenCx<'_, 'll>, target_data: llvm_sys::target::LLVMTargetDataRef) -> Self{ let mut builder = OsdiTyBuilder{ ctx, target_data, @@ -733,8 +733,8 @@ fn gen_llvm_tys<'a>(tys: &IndexMap<&'a str, OsdiStruct<'a>, RandomState>) -> Str struct OsdiTyBuilder<'a, 'b, 'll>{ ctx: &'a CodegenCx<'b, 'll>, - target_data: &'a llvm::TargetData, - #(#fields2 : Option<&'ll llvm::Type>),* + target_data: llvm_sys::target::LLVMTargetDataRef, + #(#fields2 : Option<&'ll llvm_sys::LLVMType>),* } impl<'ll> OsdiTyBuilder<'_, '_, 'll>{ diff --git a/verilogae/verilogae/Cargo.toml b/verilogae/verilogae/Cargo.toml index 8b7b0c4..a15f4ae 100644 --- a/verilogae/verilogae/Cargo.toml +++ b/verilogae/verilogae/Cargo.toml @@ -22,7 +22,8 @@ mir_llvm = { version = "0.0.0", path = "../../openvaf/mir_llvm" } mir_opt = { version = "0.0.0", path = "../../openvaf/mir_opt" } mir_autodiff = { version = "0.0.0", path = "../../openvaf/mir_autodiff" } -llvm = { version = "0.0.0", path = "../../openvaf/llvm" } +#llvm = { version = "0.0.0", path = "../../openvaf/llvm" } +llvm-sys = "181.1.1" target = { version = "0.0.0", path = "../../openvaf/target" } linker = { version = "0.0.0", path = "../../openvaf/linker" } @@ -40,7 +41,7 @@ libloading = "0.8" rayon-core = "1" -smol_str = { version = "0.2", default_features = false } +smol_str = { version = "0.2", default-features = false } typed-index-collections = "3" ahash = "0.8" diff --git a/verilogae/verilogae/src/api.rs b/verilogae/verilogae/src/api.rs index 152af3c..94d9bcd 100644 --- a/verilogae/verilogae/src/api.rs +++ b/verilogae/verilogae/src/api.rs @@ -20,7 +20,7 @@ pub struct Opts { pub allow_lints: Slice>, pub warn_lints: Slice>, pub deny_lints: Slice>, - pub opt_lvl: OptLevel, + pub opt_lvl: LLVMCodeGenOptLevel, pub target_cpu: Slice, pub target: Slice, pub cg_flags: Slice>, @@ -29,7 +29,7 @@ pub struct Opts { #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum OptLevel { +pub enum LLVMCodeGenOptLevel { None = 0, Less = 1, Default = 2, diff --git a/verilogae/verilogae/src/back.rs b/verilogae/verilogae/src/back.rs index 46db390..6f8b651 100644 --- a/verilogae/verilogae/src/back.rs +++ b/verilogae/verilogae/src/back.rs @@ -1,12 +1,13 @@ +use core::ptr::NonNull; use std::borrow::Borrow; use camino::Utf8Path; use hir::Type; use hir_lower::{CallBackKind, CurrentKind, HirInterner, ParamInfoKind, ParamKind, PlaceKind}; use lasso::Rodeo; -use llvm::{OptLevel, UNNAMED}; +use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mir::{ControlFlowGraph, FuncRef, Function}; -use mir_llvm::{Builder, BuilderVal, CallbackFun, CodegenCx, LLVMBackend}; +use mir_llvm::{Builder, BuilderVal, CallbackFun, CodegenCx, LLVMBackend, UNNAMED}; use stdx::iter::multiunzip; use typed_index_collections::TiVec; use typed_indexmap::TiSet; @@ -30,7 +31,7 @@ pub fn sim_param_str_stub<'ll>(cx: &CodegenCx<'_, 'll>) -> CallbackFun<'ll> { cx.const_callback(&[ty_str], empty_str) } -pub fn lltype<'ll>(ty: &Type, cx: &CodegenCx<'_, 'll>) -> &'ll llvm::Type { +pub fn lltype<'ll>(ty: &Type, cx: &CodegenCx<'_, 'll>) -> &'ll llvm_sys::LLVMType { match ty { Type::Real => cx.ty_double(), Type::Integer => cx.ty_int(), @@ -81,7 +82,7 @@ pub struct CodegenCtx<'a, 't> { pub model_info: &'a ModelInfo, pub llbackend: &'a LLVMBackend<'t>, pub literals: &'a mut Rodeo, - pub opt_lvl: OptLevel, + pub opt_lvl: LLVMCodeGenOptLevel, } struct Codegen<'a, 'b, 'll> { @@ -94,7 +95,12 @@ struct Codegen<'a, 'b, 'll> { } impl<'ll> Codegen<'_, '_, 'll> { - unsafe fn read_depbreak(&mut self, offset: &'ll llvm::Value, ptr: &'ll llvm::Value, ty: Type) { + unsafe fn read_depbreak( + &mut self, + offset: &'ll llvm_sys::LLVMValue, + ptr: &'ll llvm_sys::LLVMValue, + ty: Type, + ) { let vars = self.spec.dependency_breaking.iter().copied().filter(|var| var.ty(self.db) == ty); let llty = lltype(&ty, self.builder.cx); @@ -109,7 +115,7 @@ impl<'ll> Codegen<'_, '_, 'll> { self.export_names(names, &global_name); } - unsafe fn read_str_params(&mut self, ptr: &'ll llvm::Value) { + unsafe fn read_str_params(&mut self, ptr: &'ll llvm_sys::LLVMValue) { let params = self.intern.live_params(&self.func.dfg).filter_map(|(id, kind, _)| { if let ParamKind::Param(param) = *kind { (param.ty(self.db) == Type::String).then_some((id, param)) @@ -132,7 +138,12 @@ impl<'ll> Codegen<'_, '_, 'll> { self.export_names(names, &global_name); } - unsafe fn read_params(&mut self, offset: &'ll llvm::Value, ptr: &'ll llvm::Value, ty: Type) { + unsafe fn read_params( + &mut self, + offset: &'ll llvm_sys::LLVMValue, + ptr: &'ll llvm_sys::LLVMValue, + ty: Type, + ) { let params = self.intern.live_params(&self.func.dfg).filter_map(|(id, kind, _)| { if let ParamKind::Param(param) = kind { (param.ty(self.db) == ty).then_some((id, *param)) @@ -151,7 +162,11 @@ impl<'ll> Codegen<'_, '_, 'll> { self.export_names(names, &global_name); } - unsafe fn read_voltages(&mut self, offset: &'ll llvm::Value, ptr: &'ll llvm::Value) { + unsafe fn read_voltages( + &mut self, + offset: &'ll llvm_sys::LLVMValue, + ptr: &'ll llvm_sys::LLVMValue, + ) { let voltages = self.intern.live_params(&self.func.dfg).filter_map(|(id, kind, _)| { if let ParamKind::Voltage { hi, lo } = kind { Some((id, (*hi, *lo))) @@ -194,7 +209,11 @@ impl<'ll> Codegen<'_, '_, 'll> { self.export_names(names, &global_name); } - unsafe fn read_currents(&mut self, offset: &'ll llvm::Value, ptr: &'ll llvm::Value) { + unsafe fn read_currents( + &mut self, + offset: &'ll llvm_sys::LLVMValue, + ptr: &'ll llvm_sys::LLVMValue, + ) { let voltages = self.intern.live_params(&self.func.dfg).filter_map(|(id, kind, _)| { if let ParamKind::Current(kind) = kind { Some((id, *kind)) @@ -254,10 +273,10 @@ impl<'ll> Codegen<'_, '_, 'll> { unsafe fn read_fat_ptr_at( &mut self, pos: usize, - offset: &'ll llvm::Value, - ptr: &'ll llvm::Value, - ptr_ty: &'ll llvm::Type, - ) -> &'ll llvm::Value { + offset: &'ll llvm_sys::LLVMValue, + ptr: &'ll llvm_sys::LLVMValue, + ptr_ty: &'ll llvm_sys::LLVMType, + ) -> &'ll llvm_sys::LLVMValue { let builder = &mut self.builder; // get correct ptrs from array @@ -325,7 +344,7 @@ impl CodegenCtx<'_, '_> { // read parameters - let offset = unsafe { llvm::LLVMGetParam(llfun, 0) }; + let offset = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 0) }; let true_val = cx.const_bool(true); codegen.builder.params = intern @@ -343,8 +362,9 @@ impl CodegenCtx<'_, '_> { | ParamKind::Current(_) | ParamKind::HiddenState(_) => return BuilderVal::Undef, ParamKind::Temperature => unsafe { - let temperature = llvm::LLVMGetParam(llfun, 8); - codegen.read_fat_ptr_at(0, offset, temperature, cx.ty_double()) + let temperature = + llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 8); + codegen.read_fat_ptr_at(0, &*offset, &*temperature, cx.ty_double()) }, ParamKind::ParamGiven { .. } | ParamKind::PortConnected { .. } => true_val, ParamKind::ParamSysFun(param) => { @@ -363,26 +383,28 @@ impl CodegenCtx<'_, '_> { }) .collect(); - let voltages = unsafe { llvm::LLVMGetParam(llfun, 1) }; - unsafe { codegen.read_voltages(offset, voltages) }; + let voltages = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 1) }; + unsafe { codegen.read_voltages(&*offset, &*voltages) }; - let currents = unsafe { llvm::LLVMGetParam(llfun, 2) }; - unsafe { codegen.read_currents(offset, currents) }; + let currents = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 2) }; + unsafe { codegen.read_currents(&*offset, &*currents) }; - let real_params = unsafe { llvm::LLVMGetParam(llfun, 3) }; - unsafe { codegen.read_params(offset, real_params, Type::Real) }; + let real_params = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 3) }; + unsafe { codegen.read_params(&*offset, &*real_params, Type::Real) }; - let int_params = unsafe { llvm::LLVMGetParam(llfun, 4) }; - unsafe { codegen.read_params(offset, int_params, Type::Integer) }; + let int_params = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 4) }; + unsafe { codegen.read_params(&*offset, &*int_params, Type::Integer) }; - let str_params = unsafe { llvm::LLVMGetParam(llfun, 5) }; - unsafe { codegen.read_str_params(str_params) }; + let str_params = unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 5) }; + unsafe { codegen.read_str_params(&*str_params) }; - let real_dep_break = unsafe { llvm::LLVMGetParam(llfun, 6) }; - unsafe { codegen.read_depbreak(offset, real_dep_break, Type::Real) }; + let real_dep_break = + unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 6) }; + unsafe { codegen.read_depbreak(&*offset, &*real_dep_break, Type::Real) }; - let int_dep_break = unsafe { llvm::LLVMGetParam(llfun, 7) }; - unsafe { codegen.read_depbreak(offset, int_dep_break, Type::Integer) }; + let int_dep_break = + unsafe { llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 7) }; + unsafe { codegen.read_depbreak(&*offset, &*int_dep_break, Type::Integer) }; // setup callbacks @@ -406,8 +428,8 @@ impl CodegenCtx<'_, '_> { // write the return value builder.select_bb(exit_bb); - let out = llvm::LLVMGetParam(llfun, 9); - let out = builder.gep(ret_ty, out, &[offset]); + let out = llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 9); + let out = builder.gep(ret_ty, &*out, &[&*offset]); let ret_val = intern.outputs[&PlaceKind::Var(spec.var)].unwrap(); let ret_val = builder.values[ret_val].get(&builder); @@ -450,8 +472,8 @@ impl CodegenCtx<'_, '_> { intern: &HirInterner, ty: Type, builder: &mut Builder<'_, '_, 'll>, - val_ptr: &'ll llvm::Value, - param_given_ptr: &'ll llvm::Value, + val_ptr: &'ll llvm_sys::LLVMValue, + param_given_ptr: &'ll llvm_sys::LLVMValue, param_given_offset: usize, ) -> usize { let llty = lltype(&ty, builder.cx); @@ -466,7 +488,11 @@ impl CodegenCtx<'_, '_> { let off = builder.cx.const_usize(param_given_offset + offset); let ptr = builder.gep(builder.cx.ty_c_bool(), param_given_ptr, &[off]); let cbool = builder.load(builder.cx.ty_c_bool(), ptr); - builder.int_cmp(cbool, builder.cx.const_c_bool(false), llvm::IntPredicate::IntNE) + builder.int_cmp( + cbool, + builder.cx.const_c_bool(false), + llvm_sys::LLVMIntPredicate::LLVMIntNE, + ) }; let val_id = intern.params.unwrap_index(&ParamKind::Param(*param)); @@ -487,9 +513,9 @@ impl CodegenCtx<'_, '_> { &self, intern: &HirInterner, ty: Type, - builder: &Builder<'_, '_, 'll>, - val_ptr: &'ll llvm::Value, - bounds_ptrs: Option<(&'ll llvm::Value, &'ll llvm::Value)>, + builder: &mut Builder<'_, '_, 'll>, + val_ptr: &'ll llvm_sys::LLVMValue, + bounds_ptrs: Option<(&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMValue)>, ) { let llty = lltype(&ty, builder.cx); for (i, (param, _)) in @@ -528,25 +554,35 @@ impl CodegenCtx<'_, '_> { &self, cx: &CodegenCx<'_, 'll>, set: bool, - ) -> (&'ll llvm::Value, &'ll llvm::Type) { + ) -> (&'ll llvm_sys::LLVMValue, &'ll llvm_sys::LLVMType) { let name = cx.local_callback_name(); let fun_ty = cx.ty_func(&[cx.ty_ptr(), cx.ty_c_bool()], cx.ty_void()); let fun = cx.declare_int_fn(&name, fun_ty); unsafe { - let bb = llvm::LLVMAppendBasicBlockInContext(cx.llcx, fun, UNNAMED); - let builder = llvm::LLVMCreateBuilderInContext(cx.llcx); - llvm::LLVMPositionBuilderAtEnd(builder, bb); - let ptr = llvm::LLVMGetParam(fun, 0); - let flag = llvm::LLVMGetParam(fun, 1); - let val = llvm::LLVMBuildLoad2(builder, cx.ty_c_bool(), ptr, UNNAMED); + let bb = llvm_sys::core::LLVMAppendBasicBlockInContext( + NonNull::from(cx.llcx).as_ptr(), + NonNull::from(fun).as_ptr(), + UNNAMED, + ); + let builder = + llvm_sys::core::LLVMCreateBuilderInContext(NonNull::from(cx.llcx).as_ptr()); + llvm_sys::core::LLVMPositionBuilderAtEnd(builder, bb); + let ptr = llvm_sys::core::LLVMGetParam(NonNull::from(fun).as_ptr(), 0); + let flag = llvm_sys::core::LLVMGetParam(NonNull::from(fun).as_ptr(), 1); + let val = llvm_sys::core::LLVMBuildLoad2( + builder, + NonNull::from(cx.ty_c_bool()).as_ptr(), + ptr, + UNNAMED, + ); let val = if set { - llvm::LLVMBuildOr(builder, val, flag, UNNAMED) + llvm_sys::core::LLVMBuildOr(builder, val, flag, UNNAMED) } else { - llvm::LLVMBuildAnd(builder, val, flag, UNNAMED) + llvm_sys::core::LLVMBuildAnd(builder, val, flag, UNNAMED) }; - llvm::LLVMBuildStore(builder, val, ptr); - llvm::LLVMBuildRetVoid(builder); - llvm::LLVMDisposeBuilder(builder); + llvm_sys::core::LLVMBuildStore(builder, val, ptr); + llvm_sys::core::LLVMBuildRetVoid(builder); + llvm_sys::core::LLVMDisposeBuilder(builder); } (fun, fun_ty) @@ -556,7 +592,7 @@ impl CodegenCtx<'_, '_> { &self, intern: &HirInterner, builder: &mut Builder<'_, '_, 'll>, - param_flags: &'ll llvm::Value, + param_flags: &'ll llvm_sys::LLVMValue, real_cnt: usize, int_cnt: usize, ) { @@ -618,7 +654,11 @@ impl CodegenCtx<'_, '_> { param_init_func: Function, param_init_intern: HirInterner, ) { - let module = unsafe { self.llbackend.new_module("model_info", OptLevel::None).unwrap() }; + let module = unsafe { + self.llbackend + .new_module("model_info", LLVMCodeGenOptLevel::LLVMCodeGenLevelNone) + .unwrap() + }; let cx = unsafe { self.llbackend.new_ctx(self.literals, &module) }; let (fun_names, fun_symbols) = interned_model.functions(&cx); @@ -689,9 +729,11 @@ impl CodegenCtx<'_, '_> { }) .collect(); - let param_flags = unsafe { llvm::LLVMGetParam(llfun, 7) }; + let param_flags = + unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 7) }; - let param_val_real = unsafe { llvm::LLVMGetParam(llfun, 0) }; + let param_val_real = + unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 0) }; let real_cnt = self.read_params( ¶m_init_intern, Type::Real, @@ -701,7 +743,8 @@ impl CodegenCtx<'_, '_> { 0, ); - let param_val_int = unsafe { llvm::LLVMGetParam(llfun, 1) }; + let param_val_int = + unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 1) }; let int_cnt = self.read_params( ¶m_init_intern, Type::Integer, @@ -711,7 +754,8 @@ impl CodegenCtx<'_, '_> { real_cnt, ); - let param_val_str = unsafe { llvm::LLVMGetParam(llfun, 2) }; + let param_val_str = + unsafe { &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 2) }; self.read_params( ¶m_init_intern, Type::String, @@ -746,27 +790,27 @@ impl CodegenCtx<'_, '_> { // write the return values builder.select_bb(postorder[0]); - let param_min_real = llvm::LLVMGetParam(llfun, 3); - let param_max_real = llvm::LLVMGetParam(llfun, 5); + let param_min_real = &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 3); + let param_max_real = &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 5); self.write_params( ¶m_init_intern, Type::Real, - &builder, + &mut builder, param_val_real, Some((param_min_real, param_max_real)), ); - let param_min_int = llvm::LLVMGetParam(llfun, 4); - let param_max_int = llvm::LLVMGetParam(llfun, 6); + let param_min_int = &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 4); + let param_max_int = &*llvm_sys::core::LLVMGetParam(NonNull::from(llfun).as_ptr(), 6); self.write_params( ¶m_init_intern, Type::Integer, - &builder, + &mut builder, param_val_int, Some((param_min_int, param_max_int)), ); - self.write_params(¶m_init_intern, Type::String, &builder, param_val_str, None); + self.write_params(¶m_init_intern, Type::String, &mut builder, param_val_str, None); builder.ret_void(); } @@ -783,18 +827,18 @@ impl InternedModel<'_> { fn functions<'ll>( &self, cx: &CodegenCx<'_, 'll>, - ) -> (Vec<&'ll llvm::Value>, Vec<&'ll llvm::Value>) { + ) -> (Vec<&'ll llvm_sys::LLVMValue>, Vec<&'ll llvm_sys::LLVMValue>) { self.functions .iter() .map(|func| (cx.const_str(func.name), cx.const_str(func.prefix))) .unzip() } - fn opvars<'ll>(&self, cx: &CodegenCx<'_, 'll>) -> Vec<&'ll llvm::Value> { + fn opvars<'ll>(&self, cx: &CodegenCx<'_, 'll>) -> Vec<&'ll llvm_sys::LLVMValue> { self.opvars.iter().map(|name| cx.const_str(*name)).collect() } - fn nodes<'ll>(&self, cx: &CodegenCx<'_, 'll>) -> Vec<&'ll llvm::Value> { + fn nodes<'ll>(&self, cx: &CodegenCx<'_, 'll>) -> Vec<&'ll llvm_sys::LLVMValue> { self.nodes.iter().map(|name| cx.const_str(*name)).collect() } @@ -833,8 +877,8 @@ impl InternedModel<'_> { } struct ParamInfo<'ll> { - names: Vec<&'ll llvm::Value>, - units: Vec<&'ll llvm::Value>, - descriptions: Vec<&'ll llvm::Value>, - groups: Vec<&'ll llvm::Value>, + names: Vec<&'ll llvm_sys::LLVMValue>, + units: Vec<&'ll llvm_sys::LLVMValue>, + descriptions: Vec<&'ll llvm_sys::LLVMValue>, + groups: Vec<&'ll llvm_sys::LLVMValue>, } diff --git a/verilogae/verilogae/src/lib.rs b/verilogae/verilogae/src/lib.rs index a124fa1..1bb8cb2 100644 --- a/verilogae/verilogae/src/lib.rs +++ b/verilogae/verilogae/src/lib.rs @@ -11,7 +11,7 @@ use libloading::os::unix::Library; #[cfg(windows)] use libloading::os::windows::Library; use linker::link; -pub use llvm::OptLevel; +pub use llvm_sys::target_machine::LLVMCodeGenOptLevel; use mir_llvm::LLVMBackend; use salsa::ParallelDatabase; use stdx::iter::zip; diff --git a/verilogae/verilogae/src/opts.rs b/verilogae/verilogae/src/opts.rs index 2c6b135..133ac24 100644 --- a/verilogae/verilogae/src/opts.rs +++ b/verilogae/verilogae/src/opts.rs @@ -6,15 +6,23 @@ use camino::{Utf8Path, Utf8PathBuf}; use paths::AbsPathBuf; use target::spec::Target; -use crate::api::{OptLevel, Opts, Slice}; +use crate::api::{LLVMCodeGenOptLevel, Opts, Slice}; -impl From for llvm::OptLevel { - fn from(lvl: OptLevel) -> Self { +impl From for llvm_sys::target_machine::LLVMCodeGenOptLevel { + fn from(lvl: LLVMCodeGenOptLevel) -> Self { match lvl { - OptLevel::None => llvm::OptLevel::None, - OptLevel::Less => llvm::OptLevel::Less, - OptLevel::Default => llvm::OptLevel::Default, - OptLevel::Aggressive => llvm::OptLevel::Aggressive, + LLVMCodeGenOptLevel::None => { + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone + } + LLVMCodeGenOptLevel::Less => { + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelLess + } + LLVMCodeGenOptLevel::Default => { + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault + } + LLVMCodeGenOptLevel::Aggressive => { + llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive + } } } } diff --git a/verilogae/verilogae_ffi/src/ffi/generated.rs b/verilogae/verilogae_ffi/src/ffi/generated.rs index 2f756eb..642b496 100644 --- a/verilogae/verilogae_ffi/src/ffi/generated.rs +++ b/verilogae/verilogae_ffi/src/ffi/generated.rs @@ -3,7 +3,7 @@ use super::{FatPtr, NativePath}; #[repr(i32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum OptLevel { +pub enum LLVMCodeGenOptLevel { None = 0, Less = 1, Default = 2, @@ -59,7 +59,7 @@ pub struct Opts { pub allow_lints: Slice>, pub warn_lints: Slice>, pub deny_lints: Slice>, - pub opt_lvl: OptLevel, + pub opt_lvl: LLVMCodeGenOptLevel, pub target_cpu: Slice, pub target: Slice, pub cg_flags: Slice>, diff --git a/verilogae/verilogae_ffi/src/tests.rs b/verilogae/verilogae_ffi/src/tests.rs index cc26cb9..556c470 100644 --- a/verilogae/verilogae_ffi/src/tests.rs +++ b/verilogae/verilogae_ffi/src/tests.rs @@ -27,7 +27,7 @@ fn gen_ffi() { ensure_file_contents(&c_header, &c_header_content); let res = cmd!(sh, "bindgen {cpp_header} --no-layout-tests --disable-name-namespacing --allowlist-function vae::verilogae_.* ---rustified-enum vae::OptLevel --blacklist-type=vae::NativePath --blacklist-type=vae::FatPtr --blacklist-type=vae::Meta --allowlist-var=vae::PARAM_FLAGS.* --disable-header-comment").read().unwrap(); +--rustified-enum vae::LLVMCodeGenOptLevel --blacklist-type=vae::NativePath --blacklist-type=vae::FatPtr --blacklist-type=vae::Meta --allowlist-var=vae::PARAM_FLAGS.* --disable-header-comment").read().unwrap(); let mut off = 0; for line in res.split_terminator('\n') { if line.contains("pub type") && (line.contains("__uint") || line.contains("__int")) { diff --git a/verilogae/verilogae_py/Cargo.toml b/verilogae/verilogae_py/Cargo.toml index e574f20..50b54f4 100644 --- a/verilogae/verilogae_py/Cargo.toml +++ b/verilogae/verilogae_py/Cargo.toml @@ -15,7 +15,7 @@ pyo3-ffi = { version = "0.19", features = [ "extension-module", "generate-import-lib", ] } -verilogae_ffi = { version = "1.0.0", path = "../verilogae_ffi", default_features = false } +verilogae_ffi = { version = "1.0.0", path = "../verilogae_ffi", default-features = false } libc = "0.2" [build-dependencies] diff --git a/verilogae/verilogae_py/src/ffi.rs b/verilogae/verilogae_py/src/ffi.rs index 9732324..cc9d8dc 100644 --- a/verilogae/verilogae_py/src/ffi.rs +++ b/verilogae/verilogae_py/src/ffi.rs @@ -31,11 +31,25 @@ macro_rules! zero { Init { raw: [0; ::std::mem::size_of::<$ty>()] }.data }}; } - // manual implementation of PyVarObject_HEAD_INIT macro pub const fn new_type() -> PyTypeObject { let mut res = unsafe { zero!(PyTypeObject) }; - res.ob_base.ob_base.ob_refcnt = 1; + + #[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] + { + res.ob_base.ob_base.ob_refcnt.ob_refcnt = 1; + } + + #[cfg(all(not(Py_3_12), not(Py_GIL_DISABLED)))] + { + res.ob_base.ob_base.ob_refcnt = 1; + } + + #[cfg(Py_GIL_DISABLED)] + { + res.ob_base.ob_base.ob_ref_shared.store(1, Ordering::Relaxed); + } + res.tp_basicsize = size_of::() as isize; res.tp_flags = TY_FLAGS; diff --git a/verilogae/verilogae_py/src/lib.rs b/verilogae/verilogae_py/src/lib.rs index fe150a6..6650a0b 100644 --- a/verilogae/verilogae_py/src/lib.rs +++ b/verilogae/verilogae_py/src/lib.rs @@ -73,15 +73,15 @@ pub unsafe extern "C" fn PyInit_verilogae() -> *mut PyObject { m_free: None, }; - if PyType_Ready(&mut VAE_MODEL_TY) < 0 { + if PyType_Ready(std::ptr::addr_of_mut!(VAE_MODEL_TY)) < 0 { return ptr::null_mut(); } - if PyType_Ready(&mut VAE_FUNCTION_TY) < 0 { + if PyType_Ready(std::ptr::addr_of_mut!(VAE_FUNCTION_TY)) < 0 { return ptr::null_mut(); } - if PyType_Ready(&mut VAE_PARAM_TY) < 0 { + if PyType_Ready(std::ptr::addr_of_mut!(VAE_PARAM_TY)) < 0 { return ptr::null_mut(); } diff --git a/verilogae/verilogae_py/src/model.rs b/verilogae/verilogae_py/src/model.rs index 982b007..37c3f83 100644 --- a/verilogae/verilogae_py/src/model.rs +++ b/verilogae/verilogae_py/src/model.rs @@ -36,7 +36,7 @@ pub static mut VAE_MODEL_TY: PyTypeObject = { res.tp_name = "verilogae.VaeModel\0".as_ptr() as *const c_char; res.tp_doc = "A Verilog-A module compiled and loaded with Verilog-AE\0".as_ptr() as *const c_char; - res.tp_members = unsafe { &mut VAE_MODEL_MEMBERS } as *mut _; + res.tp_members = std::ptr::addr_of_mut!(VAE_MODEL_MEMBERS) as *mut _; res.tp_dealloc = Some(VaeModel::dealloc); res }; @@ -95,7 +95,7 @@ with_offsets! { impl VaeModel { #[allow(clippy::new_ret_no_self)] pub unsafe fn new(handle: *const c_void, full: bool) -> *mut PyObject { - let ptr = VAE_MODEL_TY.tp_alloc.unwrap()(&mut VAE_MODEL_TY, 0); + let ptr = VAE_MODEL_TY.tp_alloc.unwrap()(std::ptr::addr_of_mut!(VAE_MODEL_TY), 0); if ptr.is_null() { return ptr::null_mut(); } @@ -157,7 +157,7 @@ pub static mut VAE_PARAM_TY: PyTypeObject = { res.tp_name = "verilogae.VaeParam\0".as_ptr() as *const c_char; res.tp_doc = "A parameter belonging to Verilog-A module compiled and loaded with Verilog-AE\0" .as_ptr() as *const c_char; - res.tp_members = unsafe { &mut VAE_PARAM_MEMBERS } as *mut _; + res.tp_members = std::ptr::addr_of_mut!(VAE_PARAM_MEMBERS) as *mut _; res.tp_dealloc = Some(VaeParam::dealloc); res }; @@ -418,7 +418,7 @@ impl VaeParam { unit: *const c_char, group: *const c_char, ) -> (*mut PyObject, *mut PyObject) { - let ptr = VAE_PARAM_TY.tp_alloc.unwrap()(&mut VAE_PARAM_TY, 0); + let ptr = VAE_PARAM_TY.tp_alloc.unwrap()(std::ptr::addr_of_mut!(VAE_PARAM_TY), 0); if ptr.is_null() { Py_XDECREF(default); Py_XDECREF(min); @@ -471,8 +471,8 @@ pub static mut VAE_FUNCTION_TY: PyTypeObject = { res.tp_name = "verilogae.VaeFun\0".as_ptr() as *const c_char; res.tp_doc = "A function (compiled with VerilogAE) to calculate a Verilog-A variable marked with `retrieve`\0".as_ptr() as *const c_char; - res.tp_members = unsafe { &mut VAE_FUNCTION_MEMBERS } as *mut _; - res.tp_methods = unsafe { &mut VAE_FUNCTION_METHODS } as *mut _; + res.tp_members = std::ptr::addr_of_mut!(VAE_FUNCTION_MEMBERS) as *mut _; + res.tp_methods = std::ptr::addr_of_mut!(VAE_FUNCTION_METHODS) as *mut _; res.tp_dealloc = Some(VaeFun::dealloc); res }; @@ -704,7 +704,7 @@ impl VaeFun { } #[allow(clippy::new_ret_no_self)] unsafe fn new(handle: *const c_void, name: *mut PyObject, sym: *const c_char) -> *mut PyObject { - let ptr = PyType_GenericAlloc(&mut VAE_FUNCTION_TY, 0); + let ptr = PyType_GenericAlloc(std::ptr::addr_of_mut!(VAE_FUNCTION_TY), 0); if ptr.is_null() { return ptr::null_mut(); } @@ -1091,7 +1091,8 @@ fn is_array(ty: *mut PyTypeObject) -> bool { #[inline(always)] unsafe fn is_float(ty: *mut PyTypeObject) -> bool { - ty == &mut PyFloat_Type || PyType_IsSubtype(ty, &mut PyFloat_Type) != 0 + ty == std::ptr::addr_of_mut!(PyFloat_Type) + || PyType_IsSubtype(ty, std::ptr::addr_of_mut!(PyFloat_Type)) != 0 } #[inline(always)] From e391d92fbb6deb35985b69aef597783128e1b27d Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Fri, 1 Nov 2024 09:38:23 +0100 Subject: [PATCH 4/9] Allow compilation using msys2 toolchain --- .cargo/config.toml | 1 - .gitignore | 1 + openvaf/linker/src/lib.rs | 20 ++++++---- openvaf/osdi/src/metadata/osdi_0_4.rs | 3 ++ openvaf/target/build.rs | 37 +++++++++++++++++-- openvaf/target/src/lib.rs | 10 ++++- openvaf/target/src/spec.rs | 2 + openvaf/target/src/spec/windows_base.rs | 9 +++++ openvaf/target/src/spec/windows_msvc_base.rs | 33 ++++++++--------- .../target/src/spec/x86_64_pc_windows_gnu.rs | 18 +++++++++ openvaf/target/src/ucrt.c | 8 +++- 11 files changed, 111 insertions(+), 31 deletions(-) create mode 100644 openvaf/target/src/spec/windows_base.rs create mode 100644 openvaf/target/src/spec/x86_64_pc_windows_gnu.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index ad71f3b..937bb92 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -24,7 +24,6 @@ rustflags = [ # "-Aclippy::implicit_clone", # "-Ctarget-cpu=native", - "-Clink-arg=-fuse-ld=lld", # "-Clink-arg=-Wl,--no-rosegment", ] diff --git a/.gitignore b/.gitignore index 9a1238c..ed8a4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ markus_notes .aider* .env **.swp +**.swo diff --git a/openvaf/linker/src/lib.rs b/openvaf/linker/src/lib.rs index 3e17b51..7c1c1a5 100644 --- a/openvaf/linker/src/lib.rs +++ b/openvaf/linker/src/lib.rs @@ -141,17 +141,23 @@ fn get_linker<'a>( cmd.env("PATH", env::join_paths(new_path).unwrap()); Box::new(MsvcLinker { cmd }) as Box } - LinkerFlavor::Ld => { - Box::new(LdLinker { cmd: Command::new(path.unwrap_or_else(|| "ld".into())), target }) - as Box - } - LinkerFlavor::Ld64 => { - Box::new(LdLinker { cmd: Command::new(path.unwrap_or_else(|| "ld".into())), target }) - as Box + LinkerFlavor::Ld | LinkerFlavor::Ld64 => { + let path = path.unwrap_or_else(|| { + if is_msys2_environment() { + "gcc".into() + } else { + "ld".into() + } + }); + Box::new(LdLinker { cmd: Command::new(path), target }) as Box } } } +fn is_msys2_environment() -> bool { + env::var("MSYSTEM").is_ok() +} + fn exec_linker(mut cmd: std::process::Command, _out_filename: &Utf8Path) -> io::Result { match cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { #[allow(clippy::let_and_return)] diff --git a/openvaf/osdi/src/metadata/osdi_0_4.rs b/openvaf/osdi/src/metadata/osdi_0_4.rs index d74bfa1..f65384b 100644 --- a/openvaf/osdi/src/metadata/osdi_0_4.rs +++ b/openvaf/osdi/src/metadata/osdi_0_4.rs @@ -14,6 +14,8 @@ const STDLIB_BITCODE_AARCH64_PC_WINDOWS_MSVC: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/stdlib_0_4_aarch64-pc-windows-msvc.bc")); const STDLIB_BITCODE_ARM64_APPLE_MACOSX11_0_0: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/stdlib_0_4_arm64-apple-macosx11.0.0.bc")); +const STDLIB_BITCODE_X86_64_PC_WINDOWS_GNU: &[u8] = + include_bytes!(concat!(env!("OUT_DIR"), "/stdlib_0_4_x86_64-pc-windows-gnu.bc")); pub fn stdlib_bitcode(target: &target::spec::Target) -> &'static [u8] { match &*target.llvm_target { "x86_64-unknown-linux-gnu" => STDLIB_BITCODE_X86_64_UNKNOWN_LINUX_GNU, @@ -22,6 +24,7 @@ pub fn stdlib_bitcode(target: &target::spec::Target) -> &'static [u8] { "aarch64-unknown-linux-gnu" => STDLIB_BITCODE_AARCH64_UNKNOWN_LINUX_GNU, "aarch64-pc-windows-msvc" => STDLIB_BITCODE_AARCH64_PC_WINDOWS_MSVC, "arm64-apple-macosx11.0.0" => STDLIB_BITCODE_ARM64_APPLE_MACOSX11_0_0, + "x86_64-pc-windows-gnu" => STDLIB_BITCODE_X86_64_PC_WINDOWS_GNU, triple => unreachable!("unknown target triple {triple}"), } } diff --git a/openvaf/target/build.rs b/openvaf/target/build.rs index 13db6e5..79781ac 100644 --- a/openvaf/target/build.rs +++ b/openvaf/target/build.rs @@ -8,11 +8,16 @@ use xshell::{cmd, Shell}; fn main() { println!("cargo:rustc-env=CFG_COMPILER_HOST_TRIPLE={}", std::env::var("TARGET").unwrap()); // If we're just running `check`, there's no need to actually compute the stdlib just - // popualte dummys + // populate dummies let check = tracked_env_var_os("RUST_CHECK").is_some(); let sh = Shell::new().unwrap(); - gen_msvcrt_importlib(&sh, "x64", "x86_64", check); - gen_msvcrt_importlib(&sh, "arm64", "aarch64", check); + if is_msys2_environment() { + gen_msys2_importlib(&sh, "x64", "x86_64", check); + gen_msys2_importlib(&sh, "arm64", "aarch64", check); + } else { + gen_msvcrt_importlib(&sh, "x64", "x86_64", check); + gen_msvcrt_importlib(&sh, "arm64", "aarch64", check); + } } /// Reads an environment variable and adds it to dependencies. @@ -23,6 +28,10 @@ fn tracked_env_var_os + Display>(key: K) -> Option { env::var_os(key) } +fn is_msys2_environment() -> bool { + env::var("MSYSTEM").is_ok() +} + fn gen_msvcrt_importlib(sh: &Shell, arch: &str, target: &str, check: bool) { let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_file = out_dir.join(format!("ucrt_{arch}.lib")); @@ -51,3 +60,25 @@ fn gen_msvcrt_importlib(sh: &Shell, arch: &str, target: &str, check: bool) { let _ = sh.remove_path(lib); } } + +fn gen_msys2_importlib(sh: &Shell, arch: &str, _target: &str, check: bool) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let out_file = out_dir.join(format!("ucrt_{arch}.lib")); + if check { + sh.write_file(out_file, []).expect("failed to write dummy file"); + return; + } + let mut libs = Vec::new(); + let ucrt_src = stdx::project_root().join("openvaf").join("target").join("src").join("ucrt.c"); + println!("cargo:rerun-if-changed={}", ucrt_src.display()); + let ucrt_obj = out_dir.join(format!("ucrt_{arch}.obj")); + cmd!(sh, "cc -c -o {ucrt_obj} {ucrt_src}").run().expect("ucrt compilation succeeds"); + libs.push(ucrt_obj); + + let libs_ref = &libs; + cmd!(sh, "ar rcs {out_file} {libs_ref...}").run().expect("successful linking"); + + for lib in &libs { + let _ = sh.remove_path(lib); + } +} diff --git a/openvaf/target/src/lib.rs b/openvaf/target/src/lib.rs index 73a70fc..82fc4b2 100644 --- a/openvaf/target/src/lib.rs +++ b/openvaf/target/src/lib.rs @@ -18,5 +18,13 @@ pub fn host_triple() -> &'static str { // Instead of grabbing the host triple (for the current host), we grab (at // compile time) the target triple that this rustc is built with and // calling that (at runtime) the host triple. - (env!("CFG_COMPILER_HOST_TRIPLE")).rsplit_once('-').unwrap().0 + let triple = env!("CFG_COMPILER_HOST_TRIPLE"); + + // Special case for windows-gnu: preserve the full triple due to different linker flags + // under MSYS2. + if triple.contains("windows-gnu") { + triple + } else { + triple.rsplit_once('-').unwrap().0 + } } diff --git a/openvaf/target/src/spec.rs b/openvaf/target/src/spec.rs index b8baaff..a1dcfc9 100644 --- a/openvaf/target/src/spec.rs +++ b/openvaf/target/src/spec.rs @@ -1,5 +1,6 @@ mod apple_base; mod linux_base; +mod windows_base; mod windows_msvc_base; use std::collections::BTreeMap; @@ -156,6 +157,7 @@ supported_targets!( ("aarch64-unknown-linux", aarch64_unknown_linux), ("aarch64-pc-windows", aarch64_pc_windows), ("aarch64-apple-darwin", aarch64_apple_darwin), + ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu), ); impl Target { diff --git a/openvaf/target/src/spec/windows_base.rs b/openvaf/target/src/spec/windows_base.rs new file mode 100644 index 0000000..57d4ced --- /dev/null +++ b/openvaf/target/src/spec/windows_base.rs @@ -0,0 +1,9 @@ +use crate::spec::{LinkArgs, TargetOptions}; + +/// Base options for all Windows targets, excluding MSVC-specific arguments. +pub fn opts_windows_base() -> TargetOptions { + let pre_link_args = LinkArgs::new(); + let post_link_args = LinkArgs::new(); + + TargetOptions { is_like_windows: true, pre_link_args, post_link_args, ..Default::default() } +} diff --git a/openvaf/target/src/spec/windows_msvc_base.rs b/openvaf/target/src/spec/windows_msvc_base.rs index ff1b3ab..b543406 100644 --- a/openvaf/target/src/spec/windows_msvc_base.rs +++ b/openvaf/target/src/spec/windows_msvc_base.rs @@ -1,22 +1,21 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkerFlavor, TargetOptions}; +/// MSVC-specific Windows target options, extending the base Windows options. pub fn opts() -> TargetOptions { - let pre_link_args_msvc = vec![ - // Suppress the verbose logo and authorship debugging output, which would needlessly - // clog any log files. - "/NOLOGO".to_string(), - ]; - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc); + let mut base = super::windows_base::opts_windows_base(); - let mut post_link_args = LinkArgs::new(); - post_link_args.insert(LinkerFlavor::Msvc, vec!["msvcrt.lib".to_owned()]); + // Suppress the verbose logo and authorship debugging output, which would needlessly + // clog any log files. + // Add MSVC-specific linker arguments like `/NOLOGO` and `msvcrt.lib` + base.pre_link_args + .entry(LinkerFlavor::Msvc) + .or_insert_with(Vec::new) + .push("/NOLOGO".to_string()); - TargetOptions { - is_like_windows: true, - linker_flavor: LinkerFlavor::Msvc, - pre_link_args, - post_link_args, - ..Default::default() - } + base.post_link_args + .entry(LinkerFlavor::Msvc) + .or_insert_with(Vec::new) + .push("msvcrt.lib".to_string()); + + base } diff --git a/openvaf/target/src/spec/x86_64_pc_windows_gnu.rs b/openvaf/target/src/spec/x86_64_pc_windows_gnu.rs new file mode 100644 index 0000000..52386fe --- /dev/null +++ b/openvaf/target/src/spec/x86_64_pc_windows_gnu.rs @@ -0,0 +1,18 @@ +use crate::spec::{LinkerFlavor, Target}; + +pub fn target() -> Target { + let mut base = super::windows_base::opts_windows_base(); + base.cpu = "x86-64".to_string(); + base.linker_flavor = LinkerFlavor::Ld; + base.pre_link_args.insert(LinkerFlavor::Ld, vec!["-m64".to_string()]); + + Target { + llvm_target: "x86_64-pc-windows-gnu".to_string(), + arch: "x86_64".to_string(), + data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .to_string(), + options: base, + pointer_width: 64, + } +} + diff --git a/openvaf/target/src/ucrt.c b/openvaf/target/src/ucrt.c index 18842b7..ff2aed1 100644 --- a/openvaf/target/src/ucrt.c +++ b/openvaf/target/src/ucrt.c @@ -1,8 +1,12 @@ #define NULL ((void *)0) #define _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR 0x0002ULL +#ifdef __MINGW32__ +#include +#else typedef void* _locale_t; -typedef char * va_list; +typedef char* va_list; +#endif int __cdecl __stdio_common_vsprintf(unsigned __int64 options, char *str, size_t len, const char *format, _locale_t locale, va_list valist); int __cdecl snprintf (char * __restrict__ __stream, size_t __n, const char * __restrict__ __format, ...) @@ -13,4 +17,4 @@ int __cdecl snprintf (char * __restrict__ __stream, size_t __n, const char * __r ret = __stdio_common_vsprintf(_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, __stream, __n, __format, NULL, ap); __builtin_va_end(ap); return ret; -} \ No newline at end of file +} From 559df9705144b500866e592d6ed28af576f9ff5e Mon Sep 17 00:00:00 2001 From: Adrien Luitot <23219818+adrienluitot@users.noreply.github.com> Date: Sat, 30 Nov 2024 01:20:36 +0100 Subject: [PATCH 5/9] Creating CI allowing compilation on apple darwin on arm64 --- .gitattributes | 1 + .github/workflows/rust-ci.yml | 174 ++++++++++++++++++ Cargo.lock | 1 - openvaf/mir_llvm/Cargo.toml | 2 +- openvaf/sim_back/src/lib.rs | 50 +++-- openvaf/target/build.rs | 13 +- openvaf/target/src/lib.rs | 2 +- .../target/src/spec/x86_64_apple_darwin.rs | 1 - openvaf/target/src/ucrt.c | 4 + 9 files changed, 211 insertions(+), 37 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/rust-ci.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c916970 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ungram text eol=lf diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml new file mode 100644 index 0000000..64b84ee --- /dev/null +++ b/.github/workflows/rust-ci.yml @@ -0,0 +1,174 @@ +name: Rust CI + +on: + push: + branches: + - '**' + pull_request: + branches: + - '**' + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Check code formatting + run: cargo fmt -- --check + + machete: + runs-on: ubuntu-latest + steps: + - name: Setup sccache + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + uses: mozilla-actions/sccache-action@v0.0.6 + - name: Configure sccache + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + run: | + echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV + echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Install cargo-machete + run: cargo install cargo-machete + - name: Run cargo machete + run: cargo machete + + ubuntu-build-test: + runs-on: ubuntu-latest + needs: [format, machete] + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + targets: x86_64-pc-windows-gnu + - name: Setup sccache + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + uses: mozilla-actions/sccache-action@v0.0.6 + - name: Configure sccache + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + run: | + echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV + echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV + - name: Install LLVM 18 and Windows cross-compilation tools + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 18 + sudo apt-get install -y llvm-18 llvm-18-dev libclang-18-dev + + # Install llvm-lib for Windows cross-compilation + sudo apt-get install -y mingw-w64 + + # Create symlink for llvm-lib + sudo ln -s /usr/bin/llvm-ar-18 /usr/local/bin/llvm-lib + + # Verify installation + which llvm-lib + llvm-lib --version + - name: Set LLVM environment variables + run: | + echo "LLVM_SYS_181_PREFIX=/usr/lib/llvm-18" >> $GITHUB_ENV + echo "CLANG_PATH=/usr/lib/llvm-18/bin/clang" >> $GITHUB_ENV + echo "PATH=/usr/lib/llvm-18/bin:$PATH" >> $GITHUB_ENV + echo "RUST_BACKTRACE=1" >> $GITHUB_ENV + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential + - name: Build + run: cargo build --release + - name: Show sccache stats + if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + shell: bash + run: ${SCCACHE_PATH} --show-stats + # someone has to fix the errors + # - name: Run Clippy + # run: cargo clippy -- -D warnings + - name: Run tests + run: cargo test --release + + msys2-build-test: + strategy: + fail-fast: false + matrix: + sys: [MINGW64, UCRT64] + runs-on: windows-latest + needs: [format, machete] + steps: + - uses: actions/checkout@v4 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.sys }} + update: true + install: base-devel git + pacboy: >- + clang:p + llvm:p + rust:p + cc:p + python:p + sccache:p + - name: Cache sccache + uses: actions/cache@v3 + with: + path: ~/.cache/sccache + key: ${{ runner.os }}-sccache-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-sccache- + - name: Locate and configure sccache + shell: msys2 {0} + run: | + # export SCCACHE_PATH=$(which sccache) + # echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV + echo "RUSTC_WRAPPER=${SCCACHE_PATH}" >> $GITHUB_ENV + - name: Run cargo + shell: msys2 {0} + run: cargo build --release + #- name: Show sccache stats + # if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' + # shell: msys2 {0} + # run: $SCCACHE_PATH --show-stats + - name: Run tests + shell: msys2 {0} + run: cargo test --release + + macos-build-test: + strategy: + fail-fast: false + matrix: + include: + - arch: arm64 + macos: 13 + - arch: x86_64 + macos: 13 + runs-on: macos-${{ matrix.macos }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pkg-config with Homebrew + run: | + brew install pkg-config mingw-w64 sccache llvm + echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH + - name: sccache setup + run: | + # echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV + echo "RUSTC_WRAPPER=$(which sccache)" >> $GITHUB_ENV + + + - name: Build + run: cargo build --release + + - name: Run tests + run: cargo test --release + diff --git a/Cargo.lock b/Cargo.lock index fe8c99a..8e154e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -887,7 +887,6 @@ dependencies = [ "log", "mir", "target", - "target-lexicon", "typed-index-collections", ] diff --git a/openvaf/mir_llvm/Cargo.toml b/openvaf/mir_llvm/Cargo.toml index 00ffe9d..73b9059 100644 --- a/openvaf/mir_llvm/Cargo.toml +++ b/openvaf/mir_llvm/Cargo.toml @@ -13,7 +13,7 @@ doctest = false llvm-sys = {version="181.1.1", features=["prefer-dynamic"]} #llvm = { version = "0.0.0", path = "../llvm" } -target-lexicon = "0.12" +#target-lexicon = "0.12" mir = { version = "0.0.0", path = "../mir" } target = { version = "0.0.0", path = "../target" } base_n = {version = "1", path="../../lib/base_n"} diff --git a/openvaf/sim_back/src/lib.rs b/openvaf/sim_back/src/lib.rs index 65d8593..2a7d6a7 100644 --- a/openvaf/sim_back/src/lib.rs +++ b/openvaf/sim_back/src/lib.rs @@ -75,57 +75,55 @@ impl<'a> CompiledModule<'a> { let debugging = false; // && cfg!(debug_assertions); if debugging { println!("Parameters:"); - cx.intern.params.iter().for_each(|(p, val)| { + cx.intern.params.iter().for_each(|(p, val)| { print!(" {:?}", p); match p { ParamKind::Param(param) => { println!(" .. {:?} -> {:?}", param.name(db), val); - }, + } ParamKind::ParamGiven { param } => { println!(" .. {:?} -> {:?}", param.name(db), val); - }, - ParamKind::Voltage{ hi, lo} => { + } + ParamKind::Voltage { hi, lo } => { if lo.is_some() { print!(" .. V({:?},{:?})", hi.name(db), lo.unwrap().name(db)); } else { print!(" .. V({:?})", hi.name(db)); } println!(" -> {:?}", val); - }, - ParamKind::Current(ck) => { - match ck { - CurrentKind::Branch(br) => { - println!(" .. {:?} -> {:?}", br.name(db), val); - }, - CurrentKind::Unnamed{hi, lo} => { - if lo.is_some() { - print!(" .. I({:?},{:?})", hi.name(db), lo.unwrap().name(db)); - } else { - print!(" .. I({:?})", hi.name(db)); - } - println!(" -> {:?}", val); - }, - CurrentKind::Port(n) => { - println!(" .. {:?} -> {:?}", n.name(db), val); + } + ParamKind::Current(ck) => match ck { + CurrentKind::Branch(br) => { + println!(" .. {:?} -> {:?}", br.name(db), val); + } + CurrentKind::Unnamed { hi, lo } => { + if lo.is_some() { + print!(" .. I({:?},{:?})", hi.name(db), lo.unwrap().name(db)); + } else { + print!(" .. I({:?})", hi.name(db)); } + println!(" -> {:?}", val); + } + CurrentKind::Port(n) => { + println!(" .. {:?} -> {:?}", n.name(db), val); } }, - ParamKind::HiddenState (var) => { + ParamKind::HiddenState(var) => { println!(" .. {:?} -> {:?}", var.name(db), val); - }, + } // ParamKind::ImplicitUnknown ParamKind::PortConnected { port } => { println!(" .. {:?} -> {:?}", port.name(db), val); } _ => { println!(" -> {:?}", val); - }, + } } }); println!(""); println!("Outputs:"); - cx.intern.outputs.iter().for_each(|(p, val)| { + cx.intern.outputs.iter().for_each(|(p, val)| { if val.is_some() { println!(" {:?} -> {:?}", p, val.unwrap()); } else { @@ -135,7 +133,7 @@ impl<'a> CompiledModule<'a> { println!(""); println!("Tagged reads:"); - cx.intern.tagged_reads.iter().for_each(|(val, var)| { + cx.intern.tagged_reads.iter().for_each(|(val, var)| { println!(" {:?} -> {:?}", val, var); }); println!(""); @@ -145,7 +143,7 @@ impl<'a> CompiledModule<'a> { println!(" {:?} : {:?}", i, iek); } println!(""); - + let cu = db.compilation_unit(); println!("Compilation unit: {}", cu.name(db)); diff --git a/openvaf/target/build.rs b/openvaf/target/build.rs index 79781ac..371db68 100644 --- a/openvaf/target/build.rs +++ b/openvaf/target/build.rs @@ -43,12 +43,10 @@ fn gen_msvcrt_importlib(sh: &Shell, arch: &str, target: &str, check: bool) { let ucrt_src = stdx::project_root().join("openvaf").join("target").join("src").join("ucrt.c"); println!("cargo:rerun-if-changed={}", ucrt_src.display()); let ucrt_obj = out_dir.join(format!("ucrt_{arch}.obj")); - cmd!( - sh, - "clang-cl /c /Zl /GS- /clang:--target={target}-pc-windows-msvc /clang:-o{ucrt_obj} {ucrt_src}" - ) - .run() - .expect("ucrt compilation succeeds"); + let compiler = env::var("CC").unwrap_or_else(|_| "clang".to_string()); + cmd!(sh, "{compiler} -c -o {ucrt_obj} {ucrt_src} --target={target}-pc-windows-msvc") + .run() + .expect("ucrt compilation succeeds"); libs.push(ucrt_obj); let libs_ref = &libs; @@ -72,7 +70,8 @@ fn gen_msys2_importlib(sh: &Shell, arch: &str, _target: &str, check: bool) { let ucrt_src = stdx::project_root().join("openvaf").join("target").join("src").join("ucrt.c"); println!("cargo:rerun-if-changed={}", ucrt_src.display()); let ucrt_obj = out_dir.join(format!("ucrt_{arch}.obj")); - cmd!(sh, "cc -c -o {ucrt_obj} {ucrt_src}").run().expect("ucrt compilation succeeds"); + let compiler = env::var("CC").unwrap_or_else(|_| "cc".to_string()); + cmd!(sh, "{compiler} -c -o {ucrt_obj} {ucrt_src}").run().expect("ucrt compilation succeeds"); libs.push(ucrt_obj); let libs_ref = &libs; diff --git a/openvaf/target/src/lib.rs b/openvaf/target/src/lib.rs index 82fc4b2..d8b875f 100644 --- a/openvaf/target/src/lib.rs +++ b/openvaf/target/src/lib.rs @@ -22,7 +22,7 @@ pub fn host_triple() -> &'static str { // Special case for windows-gnu: preserve the full triple due to different linker flags // under MSYS2. - if triple.contains("windows-gnu") { + if triple.contains("windows-gnu") || triple.contains("apple") { triple } else { triple.rsplit_once('-').unwrap().0 diff --git a/openvaf/target/src/spec/x86_64_apple_darwin.rs b/openvaf/target/src/spec/x86_64_apple_darwin.rs index a68a71e..7a85265 100644 --- a/openvaf/target/src/spec/x86_64_apple_darwin.rs +++ b/openvaf/target/src/spec/x86_64_apple_darwin.rs @@ -8,7 +8,6 @@ pub fn target() -> Target { base.pre_link_args.insert( LinkerFlavor::Ld64, vec![ - "-m64".to_string(), "-arch".to_string(), "x86_64".to_string(), "-undefined".to_string(), diff --git a/openvaf/target/src/ucrt.c b/openvaf/target/src/ucrt.c index ff2aed1..69047b0 100644 --- a/openvaf/target/src/ucrt.c +++ b/openvaf/target/src/ucrt.c @@ -7,7 +7,10 @@ typedef void* _locale_t; typedef char* va_list; #endif +//We call this gnullvm +#if defined(__clang__) && defined(__MINGW32__) +#else int __cdecl __stdio_common_vsprintf(unsigned __int64 options, char *str, size_t len, const char *format, _locale_t locale, va_list valist); int __cdecl snprintf (char * __restrict__ __stream, size_t __n, const char * __restrict__ __format, ...) { @@ -18,3 +21,4 @@ int __cdecl snprintf (char * __restrict__ __stream, size_t __n, const char * __r __builtin_va_end(ap); return ret; } +#endif From 802bce21ac44833b52c010cb90d37e0d6fddd4ac Mon Sep 17 00:00:00 2001 From: Adrien Luitot <23219818+adrienluitot@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:53:35 +0100 Subject: [PATCH 6/9] change i8 -> c_char --- openvaf/mir_llvm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvaf/mir_llvm/src/lib.rs b/openvaf/mir_llvm/src/lib.rs index 68067a3..0525ff2 100644 --- a/openvaf/mir_llvm/src/lib.rs +++ b/openvaf/mir_llvm/src/lib.rs @@ -473,7 +473,7 @@ impl ModuleLlvm { /// An error messages in case the module invalid pub fn verify(&self) -> Option { unsafe { - let mut out_message: *mut i8 = std::ptr::null_mut(); + let mut out_message: *mut c_char = std::ptr::null_mut(); if llvm_sys::analysis::LLVMVerifyModule( self.llmod_raw, llvm_sys::analysis::LLVMVerifierFailureAction::LLVMReturnStatusAction, From 7da89a855d26c5234bade225ec4f3a23363c9bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torleif=20Sk=C3=A5r?= <16509259+tskaar@users.noreply.github.com> Date: Sun, 13 Jul 2025 17:40:16 +0200 Subject: [PATCH 7/9] mir_llvm/get_declared_value: fix null pointer dereference LLVMGetNamedGlobal _can_ return null when no global exists, but get_declared_value were unconditionally dereferencing the result. --- openvaf/mir_llvm/src/declarations.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openvaf/mir_llvm/src/declarations.rs b/openvaf/mir_llvm/src/declarations.rs index cbf3f6b..91c3676 100644 --- a/openvaf/mir_llvm/src/declarations.rs +++ b/openvaf/mir_llvm/src/declarations.rs @@ -139,10 +139,11 @@ impl<'a, 'll> CodegenCx<'a, 'll> { pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { let name = CString::new(name).unwrap(); unsafe { - Some(&*llvm_sys::core::LLVMGetNamedGlobal( + let ptr = llvm_sys::core::LLVMGetNamedGlobal( NonNull::from(self.llmod).as_ptr(), name.as_ptr(), - )) + ); + ptr.as_ref() } } From 1a1c16812f342b837e7aa9e5e53f5f3d843584bd Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Wed, 16 Jul 2025 18:09:26 +0200 Subject: [PATCH 8/9] fix: update sccache version --- .github/workflows/rust-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 64b84ee..678577a 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Setup sccache if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' - uses: mozilla-actions/sccache-action@v0.0.6 + uses: mozilla-actions/sccache-action@v0.0.9 - name: Configure sccache if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' run: | From 09896c331420313130ca3d29a7c033778e435329 Mon Sep 17 00:00:00 2001 From: Kreijstal Date: Wed, 16 Jul 2025 18:16:22 +0200 Subject: [PATCH 9/9] fix: update sccache action also on the build workflow --- .github/workflows/rust-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 678577a..009f1e0 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -52,7 +52,7 @@ jobs: targets: x86_64-pc-windows-gnu - name: Setup sccache if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' - uses: mozilla-actions/sccache-action@v0.0.6 + uses: mozilla-actions/sccache-action@v0.0.9 - name: Configure sccache if: github.event_name != 'release' && github.event_name != 'workflow_dispatch' run: |