Skip to content

Commit c12e823

Browse files
committed
final cleanups
1 parent 018c2c1 commit c12e823

File tree

4 files changed

+131
-123
lines changed

4 files changed

+131
-123
lines changed

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,8 @@ extern "C" LLVMValueRef LLVMRustGetLastInstruction(LLVMBasicBlockRef BB) {
955955
return nullptr;
956956
}
957957

958-
extern "C" void LLVMRustEraseInstUntilInclusive(LLVMBasicBlockRef bb, LLVMValueRef I) {
958+
extern "C" void LLVMRustEraseInstUntilInclusive(LLVMBasicBlockRef bb,
959+
LLVMValueRef I) {
959960
auto &BB = *unwrap(bb);
960961
auto &Inst = *unwrap<Instruction>(I);
961962
auto It = BB.begin();

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use std::sync::Arc;
1313
use rustc_arena::TypedArena;
1414
use rustc_ast::expand::StrippedCfgItem;
1515
use rustc_ast::expand::allocator::AllocatorKind;
16-
//use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs;
1716
use rustc_data_structures::fingerprint::Fingerprint;
1817
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1918
use rustc_data_structures::sorted_map::SortedMap;
@@ -1393,13 +1392,6 @@ rustc_queries! {
13931392
feedable
13941393
}
13951394

1396-
/// List of autodiff extern functions in the current crate.
1397-
//query autodiff_attrs(def_id: DefId) -> &'tcx AutoDiffAttrs {
1398-
// desc { |tcx| "computing autodiff attributes of `{}`", tcx.def_path_str(def_id) }
1399-
// arena_cache
1400-
// cache_on_disk_if { def_id.is_local() }
1401-
//}
1402-
14031395
query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
14041396
desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
14051397
}

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 7 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@
9292
//! source-level module, functions from the same module will be available for
9393
//! inlining, even when they are not marked `#[inline]`.
9494
95+
mod autodiff;
96+
9597
use std::cmp;
9698
use std::collections::hash_map::Entry;
9799
use std::fs::{self, File};
98100
use std::io::Write;
99101
use std::path::{Path, PathBuf};
100102

101-
use rustc_ast::expand::autodiff_attrs::{AutoDiffItem, DiffActivity};
102103
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
103104
use rustc_data_structures::sync;
104105
use rustc_data_structures::unord::{UnordMap, UnordSet};
@@ -114,14 +115,13 @@ use rustc_middle::mir::mono::{
114115
MonoItemPartitions, Visibility,
115116
};
116117
use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
117-
use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt};
118+
use rustc_middle::ty::{self, InstanceKind, TyCtxt};
118119
use rustc_middle::util::Providers;
119120
use rustc_session::CodegenUnits;
120121
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
121122
use rustc_span::Symbol;
122-
use rustc_symbol_mangling::symbol_name_for_instance_in_crate;
123123
use rustc_target::spec::SymbolVisibility;
124-
use tracing::{debug, trace};
124+
use tracing::debug;
125125

126126
use crate::collector::{self, MonoItemCollectionStrategy, UsageMap};
127127
use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode};
@@ -1126,60 +1126,6 @@ where
11261126
}
11271127
}
11281128

1129-
pub(crate) fn adjust_activity_to_abi<'tcx>(
1130-
tcx: TyCtxt<'tcx>,
1131-
fn_ty: Ty<'tcx>,
1132-
da: &mut Vec<DiffActivity>,
1133-
) {
1134-
if !matches!(fn_ty.kind(), ty::FnDef(..)) {
1135-
bug!("expected fn def for autodiff, got {:?}", fn_ty);
1136-
}
1137-
let fnc_binder: ty::Binder<'_, ty::FnSig<'_>> = fn_ty.fn_sig(tcx);
1138-
1139-
// If rustc compiles the unmodified primal, we know that this copy of the function
1140-
// also has correct lifetimes. We know that Enzyme won't free the shadow too early
1141-
// (or actually at all), so let's strip lifetimes when computing the layout.
1142-
let x = tcx.instantiate_bound_regions_with_erased(fnc_binder);
1143-
let mut new_activities = vec![];
1144-
let mut new_positions = vec![];
1145-
for (i, ty) in x.inputs().iter().enumerate() {
1146-
if let Some(inner_ty) = ty.builtin_deref(true) {
1147-
if ty.is_fn_ptr() {
1148-
// FIXME(ZuseZ4): add a nicer error, or just figure out how to support them,
1149-
// since Enzyme itself can handle them.
1150-
tcx.dcx().err("function pointers are currently not supported in autodiff");
1151-
}
1152-
if inner_ty.is_slice() {
1153-
// We know that the length will be passed as extra arg.
1154-
if !da.is_empty() {
1155-
// We are looking at a slice. The length of that slice will become an
1156-
// extra integer on llvm level. Integers are always const.
1157-
// However, if the slice get's duplicated, we want to know to later check the
1158-
// size. So we mark the new size argument as FakeActivitySize.
1159-
let activity = match da[i] {
1160-
DiffActivity::DualOnly
1161-
| DiffActivity::Dual
1162-
| DiffActivity::DuplicatedOnly
1163-
| DiffActivity::Duplicated => DiffActivity::FakeActivitySize,
1164-
DiffActivity::Const => DiffActivity::Const,
1165-
_ => bug!("unexpected activity for ptr/ref"),
1166-
};
1167-
new_activities.push(activity);
1168-
new_positions.push(i + 1);
1169-
}
1170-
continue;
1171-
}
1172-
}
1173-
}
1174-
// now add the extra activities coming from slices
1175-
// Reverse order to not invalidate the indices
1176-
for _ in 0..new_activities.len() {
1177-
let pos = new_positions.pop().unwrap();
1178-
let activity = new_activities.pop().unwrap();
1179-
da.insert(pos, activity);
1180-
}
1181-
}
1182-
11831129
fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitions<'_> {
11841130
let collection_strategy = match tcx.sess.opts.unstable_opts.print_mono_items {
11851131
Some(ref s) => {
@@ -1249,55 +1195,9 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
12491195
_ => None,
12501196
})
12511197
.collect();
1252-
let mut autodiff_items: Vec<AutoDiffItem> = vec![];
1253-
1254-
for (item, instance) in autodiff_mono_items {
1255-
let target_id = instance.def_id();
1256-
let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone();
1257-
let Some(target_attrs) = cg_fn_attr else {
1258-
continue;
1259-
};
1260-
//let target_attrs: &AutoDiffAttrs = tcx.autodiff_attrs(target_id);
1261-
let mut input_activities: Vec<DiffActivity> = target_attrs.input_activity.clone();
1262-
if target_attrs.is_source() {
1263-
trace!("source found: {:?}", target_id);
1264-
}
1265-
if !target_attrs.apply_autodiff() {
1266-
continue;
1267-
}
1268-
1269-
let target_symbol = symbol_name_for_instance_in_crate(tcx, instance.clone(), LOCAL_CRATE);
1270-
1271-
let source =
1272-
usage_map.used_map.get(&item).unwrap().into_iter().find_map(|item| match *item {
1273-
MonoItem::Fn(ref instance_s) => {
1274-
let source_id = instance_s.def_id();
1275-
//if tcx.autodiff_attrs(source_id).is_active() {
1276-
if let Some(ad) = &tcx.codegen_fn_attrs(source_id).autodiff_item
1277-
&& ad.is_active()
1278-
{
1279-
return Some(instance_s);
1280-
}
1281-
None
1282-
}
1283-
_ => None,
1284-
});
1285-
let inst = match source {
1286-
Some(source) => source,
1287-
None => continue,
1288-
};
1289-
1290-
debug!("source_id: {:?}", inst.def_id());
1291-
let fn_ty = inst.ty(tcx, ty::TypingEnv::fully_monomorphized());
1292-
assert!(fn_ty.is_fn());
1293-
adjust_activity_to_abi(tcx, fn_ty, &mut input_activities);
1294-
let symb = symbol_name_for_instance_in_crate(tcx, inst.clone(), LOCAL_CRATE);
1295-
1296-
let mut new_target_attrs = target_attrs.clone();
1297-
new_target_attrs.input_activity = input_activities;
1298-
let itm = new_target_attrs.into_item(symb, target_symbol);
1299-
autodiff_items.push(itm);
1300-
}
1198+
// call autodiff fnc
1199+
let autodiff_items =
1200+
autodiff::find_autodiff_source_functions(tcx, &usage_map, autodiff_mono_items);
13011201
let autodiff_items = tcx.arena.alloc_from_iter(autodiff_items);
13021202

13031203
// Output monomorphization stats per def_id
@@ -1360,13 +1260,6 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
13601260
}
13611261
}
13621262

1363-
if !autodiff_items.is_empty() {
1364-
trace!("AUTODIFF ITEMS EXIST");
1365-
for item in &mut *autodiff_items {
1366-
trace!("{}", &item);
1367-
}
1368-
}
1369-
13701263
MonoItemPartitions {
13711264
all_mono_items: tcx.arena.alloc(mono_items),
13721265
codegen_units,
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use crate::partitioning::UsageMap;
2+
use rustc_middle::mir::mono::MonoItem;
3+
use rustc_middle::bug;
4+
use rustc_ast::expand::autodiff_attrs::{AutoDiffItem, DiffActivity};
5+
use rustc_symbol_mangling::symbol_name_for_instance_in_crate;
6+
use tracing::{debug, trace};
7+
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
8+
use rustc_hir::def_id::LOCAL_CRATE;
9+
10+
fn adjust_activity_to_abi<'tcx>(
11+
tcx: TyCtxt<'tcx>,
12+
fn_ty: Ty<'tcx>,
13+
da: &mut Vec<DiffActivity>,
14+
) {
15+
if !matches!(fn_ty.kind(), ty::FnDef(..)) {
16+
bug!("expected fn def for autodiff, got {:?}", fn_ty);
17+
}
18+
let fnc_binder: ty::Binder<'_, ty::FnSig<'_>> = fn_ty.fn_sig(tcx);
19+
20+
// If rustc compiles the unmodified primal, we know that this copy of the function
21+
// also has correct lifetimes. We know that Enzyme won't free the shadow too early
22+
// (or actually at all), so let's strip lifetimes when computing the layout.
23+
let x = tcx.instantiate_bound_regions_with_erased(fnc_binder);
24+
let mut new_activities = vec![];
25+
let mut new_positions = vec![];
26+
for (i, ty) in x.inputs().iter().enumerate() {
27+
if let Some(inner_ty) = ty.builtin_deref(true) {
28+
if ty.is_fn_ptr() {
29+
// FIXME(ZuseZ4): add a nicer error, or just figure out how to support them,
30+
// since Enzyme itself can handle them.
31+
tcx.dcx().err("function pointers are currently not supported in autodiff");
32+
}
33+
if inner_ty.is_slice() {
34+
// We know that the length will be passed as extra arg.
35+
if !da.is_empty() {
36+
// We are looking at a slice. The length of that slice will become an
37+
// extra integer on llvm level. Integers are always const.
38+
// However, if the slice get's duplicated, we want to know to later check the
39+
// size. So we mark the new size argument as FakeActivitySize.
40+
let activity = match da[i] {
41+
DiffActivity::DualOnly
42+
| DiffActivity::Dual
43+
| DiffActivity::DuplicatedOnly
44+
| DiffActivity::Duplicated => DiffActivity::FakeActivitySize,
45+
DiffActivity::Const => DiffActivity::Const,
46+
_ => bug!("unexpected activity for ptr/ref"),
47+
};
48+
new_activities.push(activity);
49+
new_positions.push(i + 1);
50+
}
51+
continue;
52+
}
53+
}
54+
}
55+
// now add the extra activities coming from slices
56+
// Reverse order to not invalidate the indices
57+
for _ in 0..new_activities.len() {
58+
let pos = new_positions.pop().unwrap();
59+
let activity = new_activities.pop().unwrap();
60+
da.insert(pos, activity);
61+
}
62+
}
63+
64+
pub(crate) fn find_autodiff_source_functions<'tcx>(tcx: TyCtxt<'tcx>, usage_map: &UsageMap<'tcx>, autodiff_mono_items: Vec<(&MonoItem<'tcx>,&Instance<'tcx>)>) -> Vec<AutoDiffItem> {
65+
let mut autodiff_items: Vec<AutoDiffItem> = vec![];
66+
for (item, instance) in autodiff_mono_items {
67+
let target_id = instance.def_id();
68+
let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone();
69+
let Some(target_attrs) = cg_fn_attr else {
70+
continue;
71+
};
72+
//let target_attrs: &AutoDiffAttrs = tcx.autodiff_attrs(target_id);
73+
let mut input_activities: Vec<DiffActivity> = target_attrs.input_activity.clone();
74+
if target_attrs.is_source() {
75+
trace!("source found: {:?}", target_id);
76+
}
77+
if !target_attrs.apply_autodiff() {
78+
continue;
79+
}
80+
81+
let target_symbol = symbol_name_for_instance_in_crate(tcx, instance.clone(), LOCAL_CRATE);
82+
83+
let source =
84+
usage_map.used_map.get(&item).unwrap().into_iter().find_map(|item| match *item {
85+
MonoItem::Fn(ref instance_s) => {
86+
let source_id = instance_s.def_id();
87+
//if tcx.autodiff_attrs(source_id).is_active() {
88+
if let Some(ad) = &tcx.codegen_fn_attrs(source_id).autodiff_item
89+
&& ad.is_active()
90+
{
91+
return Some(instance_s);
92+
}
93+
None
94+
}
95+
_ => None,
96+
});
97+
let inst = match source {
98+
Some(source) => source,
99+
None => continue,
100+
};
101+
102+
debug!("source_id: {:?}", inst.def_id());
103+
let fn_ty = inst.ty(tcx, ty::TypingEnv::fully_monomorphized());
104+
assert!(fn_ty.is_fn());
105+
adjust_activity_to_abi(tcx, fn_ty, &mut input_activities);
106+
let symb = symbol_name_for_instance_in_crate(tcx, inst.clone(), LOCAL_CRATE);
107+
108+
let mut new_target_attrs = target_attrs.clone();
109+
new_target_attrs.input_activity = input_activities;
110+
let itm = new_target_attrs.into_item(symb, target_symbol);
111+
autodiff_items.push(itm);
112+
}
113+
114+
if !autodiff_items.is_empty() {
115+
trace!("AUTODIFF ITEMS EXIST");
116+
for item in &mut *autodiff_items {
117+
trace!("{}", &item);
118+
}
119+
}
120+
121+
autodiff_items
122+
}

0 commit comments

Comments
 (0)