microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
80434083bf8758d73a6cbfd98ba67a8d6ecbdc93

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc/src/codegen.rs

78lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
7use qsc_codegen::qir::fir_to_qir;
8use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
9use qsc_frontend::compile::{PackageStore, SourceMap};
10use qsc_partial_eval::ProgramEntry;
11use qsc_passes::{PackageType, PassContext};
12use qsc_rca::Analyzer;
13
14use crate::compile;
15
16pub fn get_qir(
17 sources: SourceMap,
18 language_features: LanguageFeatures,
19 capabilities: TargetCapabilityFlags,
20) -> Result<String, String> {
21 let core = compile::core();
22 let mut package_store = PackageStore::new(core);
23 let std = compile::std(&package_store, capabilities);
24 let std = package_store.insert(std);
25
26 let (unit, errors) = crate::compile::compile(
27 &package_store,
28 &[std],
29 sources,
30 PackageType::Exe,
31 capabilities,
32 language_features,
33 );
34
35 // Ensure it compiles before trying to add it to the store.
36 if !errors.is_empty() {
37 // This will happen when QIR generation is attempted on a program that has errors.
38 // This can happen in the playground.
39 let mut error_message =
40 String::from("Failed to generate QIR. Could not compile sources.:\n");
41 for error in errors {
42 error_message.push_str(&format!("{error}\n"));
43 }
44
45 return Err(error_message);
46 }
47
48 let package_id = package_store.insert(unit);
49 let (fir_store, fir_package_id) = qsc_passes::lower_hir_to_fir(&package_store, package_id);
50 let package = fir_store.get(fir_package_id);
51 let entry = ProgramEntry {
52 exec_graph: package.entry_exec_graph.clone(),
53 expr: (
54 fir_package_id,
55 package
56 .entry
57 .expect("package must have an entry expression"),
58 )
59 .into(),
60 };
61
62 let compute_properties = if capabilities == TargetCapabilityFlags::empty() {
63 // baseprofchk already handled compliance, run the analyzer to get the compute properties.
64 let analyzer = Analyzer::init(&fir_store);
65 Ok(analyzer.analyze_all())
66 } else {
67 PassContext::run_fir_passes_on_fir(&fir_store, fir_package_id, capabilities)
68 };
69
70 let Ok(compute_properties) = compute_properties else {
71 // This should never happen, as the program should be checked for errors before trying to
72 // generate code for it. But just in case, simply report the failure.
73 return Err("Failed to generate QIR. Could not generate compute properties.".to_string());
74 };
75
76 fir_to_qir(&fir_store, capabilities, Some(compute_properties), &entry)
77 .map_err(|e| e.to_string())
78}
79