Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ license = "MIT"
version = "0.0.0"

[workspace.dependencies]
arbitrary = "1"
bitflags = "2.11"
memchr = "2.8"
clap = "4.4"
Expand Down Expand Up @@ -79,6 +80,7 @@ sorted-vec = "0.8"
sorted-iter = "0.1"
wasm-bindgen = "0.2.114"
wasm-bindgen-futures = "0.4"
winnow = "0.7"
rand = "0.8"
serde_json = "1.0"
pyo3 = "0.28"
Expand Down
2 changes: 0 additions & 2 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,6 @@ def install_python_test_requirements(cwd, interpreter, check: bool = True):
requirement,
"--only-binary",
"qirrunner",
"--only-binary",
"pyqir",
]
subprocess.run(command_args, check=check, text=True, cwd=cwd)

Expand Down
1 change: 1 addition & 0 deletions source/compiler/qsc_codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ qsc_fir = { path = "../qsc_fir" }
qsc_formatter = { path = "../qsc_formatter" }
qsc_frontend = { path = "../qsc_frontend" }
qsc_hir = { path = "../qsc_hir" }
qsc_llvm = { path = "../qsc_llvm" }
qsc_lowerer = { path = "../qsc_lowerer" }
qsc_partial_eval = { path = "../qsc_partial_eval" }
qsc_rca = { path = "../qsc_rca" }
Expand Down
96 changes: 84 additions & 12 deletions source/compiler/qsc_codegen/src/qir.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use qsc_data_structures::target::{Profile, TargetCapabilityFlags};
use qsc_eval::val::Value;
use qsc_data_structures::{
span::Span,
target::{Profile, TargetCapabilityFlags},
};
use qsc_eval::{PackageSpan, val::Value};
use qsc_llvm::qir::QirProfile;
use qsc_lowerer::map_fir_package_to_hir;
use qsc_partial_eval::{
PartialEvalConfig, Program, ProgramEntry, partially_evaluate, partially_evaluate_call,
};
use qsc_rca::PackageStoreComputeProperties;
use qsc_rir::{passes::check_and_transform, rir};

pub mod v1;
pub mod v2;
mod common;

/// converts the given sources to RIR using the given language features.
pub fn fir_to_rir(
Expand Down Expand Up @@ -49,11 +53,58 @@ pub fn fir_to_qir(
},
)?;
check_and_transform(&mut program);
if capabilities <= Profile::AdaptiveRIF.into() {
Ok(v1::ToQir::<String>::to_qir(&program, &program))
} else {
Ok(v2::ToQir::<String>::to_qir(&program, &program))
let module = build_module(&program, capabilities);
#[cfg(debug_assertions)]
{
let ir_errors = qsc_llvm::validate_ir(&module);
assert!(
ir_errors.is_empty(),
"codegen produced invalid IR in fir_to_qir: {ir_errors:?}"
);
}
Ok(qsc_llvm::write_module_to_string(&module))
}

/// converts the given sources to QIR bitcode using the given language features.
pub fn fir_to_qir_bitcode(
fir_store: &qsc_fir::fir::PackageStore,
capabilities: TargetCapabilityFlags,
compute_properties: Option<PackageStoreComputeProperties>,
entry: &ProgramEntry,
) -> Result<Vec<u8>, qsc_partial_eval::Error> {
let mut program = get_rir_from_compilation(
fir_store,
compute_properties,
entry,
capabilities,
PartialEvalConfig {
generate_debug_metadata: false,
},
)?;
check_and_transform(&mut program);
let module = build_module(&program, capabilities);
#[cfg(debug_assertions)]
{
let ir_errors = qsc_llvm::validate_ir(&module);
assert!(
ir_errors.is_empty(),
"codegen produced invalid IR in fir_to_qir_bitcode: {ir_errors:?}"
);
}
qsc_llvm::try_write_bitcode(&module).map_err(|error| bitcode_write_error(entry, &error))
}

fn bitcode_write_error(
entry: &ProgramEntry,
error: &qsc_llvm::WriteError,
) -> qsc_partial_eval::Error {
qsc_partial_eval::Error::Unexpected(
format!("QIR bitcode emission failed: {error}"),
PackageSpan {
package: map_fir_package_to_hir(entry.expr.package),
span: Span::default(),
},
)
}

/// converts the given callable to QIR using the given arguments and language features.
Expand All @@ -80,11 +131,16 @@ pub fn fir_to_qir_from_callable(
},
)?;
check_and_transform(&mut program);
if capabilities <= Profile::AdaptiveRIF.into() {
Ok(v1::ToQir::<String>::to_qir(&program, &program))
} else {
Ok(v2::ToQir::<String>::to_qir(&program, &program))
let module = build_module(&program, capabilities);
#[cfg(debug_assertions)]
{
let ir_errors = qsc_llvm::validate_ir(&module);
assert!(
ir_errors.is_empty(),
"codegen produced invalid IR in fir_to_qir_from_callable: {ir_errors:?}"
);
}
Ok(qsc_llvm::write_module_to_string(&module))
}

/// converts the given callable to RIR using the given arguments and language features.
Expand Down Expand Up @@ -114,6 +170,22 @@ pub fn fir_to_rir_from_callable(
Ok((orig, program))
}

fn build_module(
program: &rir::Program,
capabilities: TargetCapabilityFlags,
) -> qsc_llvm::model::Module {
let profile = if capabilities <= Profile::AdaptiveRIF.into() {
if program.config.is_base() {
QirProfile::BaseV1
} else {
QirProfile::AdaptiveV1
}
} else {
QirProfile::AdaptiveV2
};
common::build_qir_module(program, profile)
}

fn get_rir_from_compilation(
fir_store: &qsc_fir::fir::PackageStore,
compute_properties: Option<PackageStoreComputeProperties>,
Expand Down
Loading