Skip to content

Commit

Permalink
Use RCA and new QIR code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
idavis committed May 20, 2024
1 parent bd19ca1 commit 8adb760
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 137 deletions.
13 changes: 3 additions & 10 deletions compiler/qsc/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCap
use qsc_frontend::compile::{PackageStore, SourceMap};
use qsc_partial_eval::ProgramEntry;
use qsc_passes::{PackageType, PassContext};
use qsc_rca::Analyzer;

use crate::compile;

Expand Down Expand Up @@ -59,18 +58,12 @@ pub fn get_qir(
.into(),
};

let compute_properties = if capabilities == TargetCapabilityFlags::empty() {
// baseprofchk already handled compliance, run the analyzer to get the compute properties.
let analyzer = Analyzer::init(&fir_store);
Ok(analyzer.analyze_all())
} else {
let Ok(compute_properties) =
PassContext::run_fir_passes_on_fir(&fir_store, fir_package_id, capabilities)
};

let Ok(compute_properties) = compute_properties else {
else {
// This should never happen, as the program should be checked for errors before trying to
// generate code for it. But just in case, simply report the failure.
return Err("Failed to generate QIR. Could not generate compute properties.".to_string());
return Err("Failed to generate QIR. Program contains errors.".to_string());
};

fir_to_qir(&fir_store, capabilities, Some(compute_properties), &entry)
Expand Down
12 changes: 8 additions & 4 deletions compiler/qsc/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn compile_ast(
sources: SourceMap,
package_type: PackageType,
capabilities: TargetCapabilityFlags,
language_features: LanguageFeatures,
) -> (CompileUnit, Vec<Error>) {
let unit = qsc_frontend::compile::compile_ast(
store,
Expand All @@ -52,7 +53,7 @@ pub fn compile_ast(
capabilities,
vec![],
);
process_compile_unit(store, package_type, capabilities, unit)
process_compile_unit(store, package_type, capabilities, unit, language_features)
}

/// Compiles a package from its source representation.
Expand All @@ -72,7 +73,7 @@ pub fn compile(
capabilities,
language_features,
);
process_compile_unit(store, package_type, capabilities, unit)
process_compile_unit(store, package_type, capabilities, unit, language_features)
}

#[must_use]
Expand All @@ -82,14 +83,17 @@ fn process_compile_unit(
package_type: PackageType,
capabilities: TargetCapabilityFlags,
mut unit: CompileUnit,
language_features: LanguageFeatures,
) -> (CompileUnit, Vec<Error>) {
let mut errors = Vec::new();
for error in unit.errors.drain(..) {
errors.push(WithSource::from_map(&unit.sources, error.into()));
}

let use_baseprofck =
capabilities.is_empty() && !language_features.contains(LanguageFeatures::PreviewQirGen);
if errors.is_empty() {
for error in run_default_passes(store.core(), &mut unit, package_type, capabilities) {
for error in run_default_passes(store.core(), &mut unit, package_type, use_baseprofck) {
errors.push(WithSource::from_map(&unit.sources, error.into()));
}
}
Expand Down Expand Up @@ -126,7 +130,7 @@ pub fn core() -> CompileUnit {
#[must_use]
pub fn std(store: &PackageStore, capabilities: TargetCapabilityFlags) -> CompileUnit {
let mut unit = qsc_frontend::compile::std(store, capabilities);
let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib, capabilities);
let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib, false);
if pass_errors.is_empty() {
unit
} else {
Expand Down
10 changes: 6 additions & 4 deletions compiler/qsc/src/incremental.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ impl Compiler {
language_features,
);
let store = store.open();

let use_baseprofck =
capabilities.is_empty() && !language_features.contains(LanguageFeatures::PreviewQirGen);
Ok(Self {
store,
source_package_id,
frontend,
passes: PassContext::new(capabilities),
passes: PassContext::new(use_baseprofck),
})
}

Expand All @@ -92,12 +93,13 @@ impl Compiler {
let frontend =
qsc_frontend::incremental::Compiler::new(&store, [], capabilities, language_features);
let store = store.open();

let use_baseprofck =
capabilities.is_empty() && !language_features.contains(LanguageFeatures::PreviewQirGen);
Ok(Self {
store,
source_package_id,
frontend,
passes: PassContext::new(capabilities),
passes: PassContext::new(use_baseprofck),
})
}

Expand Down
16 changes: 2 additions & 14 deletions compiler/qsc_codegen/src/qir_base/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@ fn check(program: &str, expr: Option<&str>, expect: &Expect) {
assert!(run_core_passes(&mut core).is_empty());
let mut store = PackageStore::new(core);
let mut std = compile::std(&store, TargetCapabilityFlags::empty());
assert!(run_default_passes(
store.core(),
&mut std,
PackageType::Lib,
TargetCapabilityFlags::empty()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut std, PackageType::Lib, false).is_empty());
let std = store.insert(std);

let expr_as_arc: Option<Arc<str>> = expr.map(|s| Arc::from(s.to_string()));
Expand All @@ -39,13 +33,7 @@ fn check(program: &str, expr: Option<&str>, expect: &Expect) {
LanguageFeatures::default(),
);
assert!(unit.errors.is_empty(), "{:?}", unit.errors);
assert!(run_default_passes(
store.core(),
&mut unit,
PackageType::Exe,
TargetCapabilityFlags::empty()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut unit, PackageType::Exe, false).is_empty());
let package = store.insert(unit);

let qir = generate_qir(&store, package);
Expand Down
16 changes: 2 additions & 14 deletions compiler/qsc_codegen/src/qsharp/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,7 @@ pub(crate) fn get_compilation(sources: Option<SourceMap>) -> (PackageId, Package
assert!(run_core_passes(&mut core).is_empty());
let mut store = PackageStore::new(core);
let mut std = compile::std(&store, TargetCapabilityFlags::empty());
assert!(run_default_passes(
store.core(),
&mut std,
PackageType::Lib,
TargetCapabilityFlags::empty()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut std, PackageType::Lib, false).is_empty());
let std = store.insert(std);

let mut unit = compile(
Expand All @@ -51,13 +45,7 @@ pub(crate) fn get_compilation(sources: Option<SourceMap>) -> (PackageId, Package
LanguageFeatures::empty(),
);
assert!(unit.errors.is_empty(), "{:?}", unit.errors);
assert!(run_default_passes(
store.core(),
&mut unit,
PackageType::Lib,
TargetCapabilityFlags::all()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut unit, PackageType::Lib, false).is_empty());
let package_id = store.insert(unit);
(package_id, store)
}
Expand Down
16 changes: 2 additions & 14 deletions compiler/qsc_eval/src/intrinsic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,7 @@ fn check_intrinsic(file: &str, expr: &str, out: &mut impl Receiver) -> Result<Va

let mut std = compile::std(&store, TargetCapabilityFlags::all());
assert!(std.errors.is_empty());
assert!(run_default_passes(
store.core(),
&mut std,
PackageType::Lib,
TargetCapabilityFlags::all()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut std, PackageType::Lib, false).is_empty());
let std_fir = qsc_lowerer::Lowerer::new().lower_package(&std.package);
let std_id = store.insert(std);

Expand All @@ -173,13 +167,7 @@ fn check_intrinsic(file: &str, expr: &str, out: &mut impl Receiver) -> Result<Va
LanguageFeatures::default(),
);
assert!(unit.errors.is_empty());
assert!(run_default_passes(
store.core(),
&mut unit,
PackageType::Lib,
TargetCapabilityFlags::all()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut unit, PackageType::Lib, false).is_empty());
let unit_fir = qsc_lowerer::Lowerer::new().lower_package(&unit.package);
let entry = unit_fir.entry_exec_graph.clone();

Expand Down
30 changes: 4 additions & 26 deletions compiler/qsc_eval/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,7 @@ fn check_expr(file: &str, expr: &str, expect: &Expect) {

let mut std = compile::std(&store, TargetCapabilityFlags::all());
assert!(std.errors.is_empty());
assert!(run_default_passes(
store.core(),
&mut std,
PackageType::Lib,
TargetCapabilityFlags::all()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut std, PackageType::Lib, false).is_empty());
let std_fir = fir_lowerer.lower_package(&std.package);
let std_id = store.insert(std);

Expand All @@ -70,12 +64,7 @@ fn check_expr(file: &str, expr: &str, expect: &Expect) {
LanguageFeatures::default(),
);
assert!(unit.errors.is_empty(), "{:?}", unit.errors);
let pass_errors = run_default_passes(
store.core(),
&mut unit,
PackageType::Lib,
TargetCapabilityFlags::all(),
);
let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib, false);
assert!(pass_errors.is_empty(), "{pass_errors:?}");
let unit_fir = fir_lowerer.lower_package(&unit.package);
let entry = unit_fir.entry_exec_graph.clone();
Expand Down Expand Up @@ -117,13 +106,7 @@ fn check_partial_eval_stmt(

let mut std = compile::std(&store, TargetCapabilityFlags::all());
assert!(std.errors.is_empty());
assert!(run_default_passes(
store.core(),
&mut std,
PackageType::Lib,
TargetCapabilityFlags::all()
)
.is_empty());
assert!(run_default_passes(store.core(), &mut std, PackageType::Lib, false).is_empty());
let std_fir = qsc_lowerer::Lowerer::new().lower_package(&std.package);
let std_id = store.insert(std);

Expand All @@ -136,12 +119,7 @@ fn check_partial_eval_stmt(
LanguageFeatures::default(),
);
assert!(unit.errors.is_empty(), "{:?}", unit.errors);
let pass_errors = run_default_passes(
store.core(),
&mut unit,
PackageType::Lib,
TargetCapabilityFlags::all(),
);
let pass_errors = run_default_passes(store.core(), &mut unit, PackageType::Lib, false);
assert!(pass_errors.is_empty(), "{pass_errors:?}");
let unit_fir = qsc_lowerer::Lowerer::new().lower_package(&unit.package);
fir_expect.assert_eq(&unit_fir.to_string());
Expand Down
4 changes: 2 additions & 2 deletions compiler/qsc_passes/src/baseprofck/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ use crate::baseprofck::check_base_profile_compliance;

fn check(expr: &str, expect: &Expect) {
let mut store = PackageStore::new(compile::core());
let std = store.insert(compile::std(&store, TargetCapabilityFlags::all()));
let std = store.insert(compile::std(&store, TargetCapabilityFlags::empty()));
let sources = SourceMap::new([("test".into(), "".into())], Some(expr.into()));
let unit = compile(
&store,
&[std],
sources,
TargetCapabilityFlags::all(),
TargetCapabilityFlags::empty(),
LanguageFeatures::default(),
);
assert!(unit.errors.is_empty(), "{:?}", unit.errors);
Expand Down
12 changes: 6 additions & 6 deletions compiler/qsc_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ pub fn lower_hir_to_fir(
}

pub struct PassContext {
capabilities: TargetCapabilityFlags,
use_baseprofck: bool,
borrow_check: borrowck::Checker,
}

impl PassContext {
#[must_use]
pub fn new(capabilities: TargetCapabilityFlags) -> Self {
pub fn new(use_baseprofck: bool) -> Self {
Self {
capabilities,
use_baseprofck,
borrow_check: borrowck::Checker::default(),
}
}
Expand Down Expand Up @@ -117,7 +117,7 @@ impl PassContext {
ReplaceQubitAllocation::new(core, assigner).visit_package(package);
Validator::default().visit_package(package);

let base_prof_errors = if self.capabilities == TargetCapabilityFlags::empty() {
let base_prof_errors = if self.use_baseprofck {
baseprofck::check_base_profile_compliance(package)
} else {
Vec::new()
Expand Down Expand Up @@ -148,9 +148,9 @@ pub fn run_default_passes(
core: &Table,
unit: &mut CompileUnit,
package_type: PackageType,
capabilities: TargetCapabilityFlags,
use_baseprofck: bool,
) -> Vec<Error> {
PassContext::new(capabilities).run_default_passes(
PassContext::new(use_baseprofck).run_default_passes(
&mut unit.package,
&mut unit.assigner,
core,
Expand Down
37 changes: 18 additions & 19 deletions language_service/src/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ impl Compilation {
.get(package_id)
.expect("expected to find user package");

run_fir_passes(
&mut errors,
target_profile,
&package_store,
package_id,
unit,
);
if language_features.contains(LanguageFeatures::PreviewQirGen) {
run_fir_passes(
&mut errors,
target_profile,
&package_store,
package_id,
unit,
);
}

run_linter_passes(lints_config, &mut errors, unit);

Expand Down Expand Up @@ -133,13 +135,15 @@ impl Compilation {
.get(package_id)
.expect("expected to find user package");

run_fir_passes(
&mut errors,
target_profile,
&package_store,
package_id,
unit,
);
if language_features.contains(LanguageFeatures::PreviewQirGen) {
run_fir_passes(
&mut errors,
target_profile,
&package_store,
package_id,
unit,
);
}

run_linter_passes(lints_config, &mut errors, unit);

Expand Down Expand Up @@ -257,11 +261,6 @@ fn run_fir_passes(
return;
}

if target_profile == Profile::Base {
// baseprofchk will handle the case where the target profile is Base
return;
}

if target_profile == Profile::Unrestricted {
// no point in running passes on unrestricted profile
return;
Expand Down
1 change: 1 addition & 0 deletions language_service/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use qsc_project::Manifest;
pub struct WorkspaceConfigurationUpdate {
pub target_profile: Option<Profile>,
pub package_type: Option<PackageType>,
pub language_features: Option<LanguageFeatures>,
}

#[derive(Debug)]
Expand Down
Loading

0 comments on commit 8adb760

Please sign in to comment.