Skip to content

Commit

Permalink
Auto merge of #132128 - workingjubilee:rollup-uwqp2i2, r=workingjubilee
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - #131457 (Expand `ptr::fn_addr_eq()` documentation.)
 - #132085 (Update StableMIR doc to reflect current status)
 - #132118 (Add support for `~const` item bounds)
 - #132125 (coverage: Emit LLVM intrinsics using the normal helper method)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 25, 2024
2 parents 017ae1b + 7f93af1 commit 97ae1df
Show file tree
Hide file tree
Showing 20 changed files with 273 additions and 259 deletions.
10 changes: 0 additions & 10 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1725,16 +1725,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
self.fptoint_sat(true, val, dest_ty)
}

fn instrprof_increment(
&mut self,
_fn_name: RValue<'gcc>,
_hash: RValue<'gcc>,
_num_counters: RValue<'gcc>,
_index: RValue<'gcc>,
) {
unimplemented!();
}
}

impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
Expand Down
100 changes: 21 additions & 79 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,39 +1165,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
self.call_lifetime_intrinsic("llvm.lifetime.end.p0i8", ptr, size);
}

fn instrprof_increment(
&mut self,
fn_name: &'ll Value,
hash: &'ll Value,
num_counters: &'ll Value,
index: &'ll Value,
) {
debug!(
"instrprof_increment() with args ({:?}, {:?}, {:?}, {:?})",
fn_name, hash, num_counters, index
);

let llfn = unsafe { llvm::LLVMRustGetInstrProfIncrementIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_i32()],
self.cx.type_void(),
);
let args = &[fn_name, hash, num_counters, index];
let args = self.check_call("call", llty, llfn, args);

unsafe {
let _ = llvm::LLVMRustBuildCall(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
[].as_ptr(),
0 as c_uint,
);
}
}

fn call(
&mut self,
llty: &'ll Type,
Expand Down Expand Up @@ -1667,6 +1634,18 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
kcfi_bundle
}

/// Emits a call to `llvm.instrprof.increment`. Used by coverage instrumentation.
#[instrument(level = "debug", skip(self))]
pub(crate) fn instrprof_increment(
&mut self,
fn_name: &'ll Value,
hash: &'ll Value,
num_counters: &'ll Value,
index: &'ll Value,
) {
self.call_intrinsic("llvm.instrprof.increment", &[fn_name, hash, num_counters, index]);
}

/// Emits a call to `llvm.instrprof.mcdc.parameters`.
///
/// This doesn't produce any code directly, but is used as input by
Expand All @@ -1676,80 +1655,43 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
///
/// [`CodeGenPGO::emitMCDCParameters`]:
/// https://github.com/rust-lang/llvm-project/blob/5399a24/clang/lib/CodeGen/CodeGenPGO.cpp#L1124
#[instrument(level = "debug", skip(self))]
pub(crate) fn mcdc_parameters(
&mut self,
fn_name: &'ll Value,
hash: &'ll Value,
bitmap_bits: &'ll Value,
) {
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bits);

assert!(
crate::llvm_util::get_version() >= (19, 0, 0),
"MCDC intrinsics require LLVM 19 or later"
);

let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
self.cx.type_void(),
);
let args = &[fn_name, hash, bitmap_bits];
let args = self.check_call("call", llty, llfn, args);

unsafe {
let _ = llvm::LLVMRustBuildCall(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
[].as_ptr(),
0 as c_uint,
);
}
self.call_intrinsic("llvm.instrprof.mcdc.parameters", &[fn_name, hash, bitmap_bits]);
}

#[instrument(level = "debug", skip(self))]
pub(crate) fn mcdc_tvbitmap_update(
&mut self,
fn_name: &'ll Value,
hash: &'ll Value,
bitmap_index: &'ll Value,
mcdc_temp: &'ll Value,
) {
debug!(
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?})",
fn_name, hash, bitmap_index, mcdc_temp
);
assert!(
crate::llvm_util::get_version() >= (19, 0, 0),
"MCDC intrinsics require LLVM 19 or later"
);

let llfn =
unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_ptr()],
self.cx.type_void(),
);
let args = &[fn_name, hash, bitmap_index, mcdc_temp];
let args = self.check_call("call", llty, llfn, args);
unsafe {
let _ = llvm::LLVMRustBuildCall(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
[].as_ptr(),
0 as c_uint,
);
}
self.call_intrinsic("llvm.instrprof.mcdc.tvbitmap.update", args);
}

#[instrument(level = "debug", skip(self))]
pub(crate) fn mcdc_condbitmap_reset(&mut self, mcdc_temp: &'ll Value) {
self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi);
}

#[instrument(level = "debug", skip(self))]
pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
debug!("mcdc_condbitmap_update() with args ({:?}, {:?})", cond_index, mcdc_temp);
assert!(
crate::llvm_util::get_version() >= (19, 0, 0),
"MCDC intrinsics require LLVM 19 or later"
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,10 @@ impl<'ll> CodegenCx<'ll, '_> {

if self.sess().instrument_coverage() {
ifn!("llvm.instrprof.increment", fn(ptr, t_i64, t_i32, t_i32) -> void);
if crate::llvm_util::get_version() >= (19, 0, 0) {
ifn!("llvm.instrprof.mcdc.parameters", fn(ptr, t_i64, t_i32) -> void);
ifn!("llvm.instrprof.mcdc.tvbitmap.update", fn(ptr, t_i64, t_i32, ptr) -> void);
}
}

ifn!("llvm.type.test", fn(ptr, t_metadata) -> i1);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
let hash = bx.const_u64(function_coverage_info.function_source_hash);
let bitmap_index = bx.const_u32(bitmap_idx);
bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);
bx.mcdc_condbitmap_reset(cond_bitmap);
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1615,10 +1615,6 @@ unsafe extern "C" {
pub fn LLVMRustSetAllowReassoc(Instr: &Value);

// Miscellaneous instructions
pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
pub fn LLVMRustGetInstrProfMCDCParametersIntrinsic(M: &Module) -> &Value;
pub fn LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(M: &Module) -> &Value;

pub fn LLVMRustBuildCall<'a>(
B: &Builder<'a>,
Ty: &'a Type,
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,6 @@ pub trait BuilderMethods<'a, 'tcx>:
/// Called for `StorageDead`
fn lifetime_end(&mut self, ptr: Self::Value, size: Size);

fn instrprof_increment(
&mut self,
fn_name: Self::Value,
hash: Self::Value,
num_counters: Self::Value,
index: Self::Value,
);

fn call(
&mut self,
llty: Self::Type,
Expand Down
39 changes: 0 additions & 39 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1531,45 +1531,6 @@ extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty,
ArrayRef<OperandBundleDef>(OpBundles)));
}

extern "C" LLVMValueRef
LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
#if LLVM_VERSION_GE(20, 0)
return wrap(llvm::Intrinsic::getOrInsertDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_increment));
#else
return wrap(llvm::Intrinsic::getDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_increment));
#endif
}

extern "C" LLVMValueRef
LLVMRustGetInstrProfMCDCParametersIntrinsic(LLVMModuleRef M) {
#if LLVM_VERSION_LT(19, 0)
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
#endif
#if LLVM_VERSION_GE(20, 0)
return wrap(llvm::Intrinsic::getOrInsertDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
#else
return wrap(llvm::Intrinsic::getDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
#endif
}

extern "C" LLVMValueRef
LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) {
#if LLVM_VERSION_LT(19, 0)
report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
#endif
#if LLVM_VERSION_GE(20, 0)
return wrap(llvm::Intrinsic::getOrInsertDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
#else
return wrap(llvm::Intrinsic::getDeclaration(
unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
#endif
}

extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst,
unsigned DstAlign, LLVMValueRef Src,
unsigned SrcAlign,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ where
})
}

/// Assemble additional assumptions for an alias that are not included
/// in the item bounds of the alias. For now, this is limited to the
/// `implied_const_bounds` for an associated type.
fn consider_additional_alias_assumptions(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
alias_ty: ty::AliasTy<I>,
) -> Vec<Candidate<I>>;

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
Expand Down Expand Up @@ -594,6 +603,8 @@ where
));
}

candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));

if kind != ty::Projection {
return;
}
Expand Down
51 changes: 50 additions & 1 deletion compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::{self as ty, Interner};
use rustc_type_ir::{self as ty, Interner, elaborate};
use tracing::instrument;

use super::assembly::Candidate;
Expand Down Expand Up @@ -70,6 +70,55 @@ where
}
}

/// Register additional assumptions for aliases corresponding to `~const` item bounds.
///
/// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
/// Instead, they only hold if the const conditons on the alias also hold. This is why
/// we also register the const conditions of the alias after matching the goal against
/// the assumption.
fn consider_additional_alias_assumptions(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
alias_ty: ty::AliasTy<I>,
) -> Vec<Candidate<I>> {
let cx = ecx.cx();
let mut candidates = vec![];

// FIXME(effects): We elaborate here because the implied const bounds
// aren't necessarily elaborated. We probably should prefix this query
// with `explicit_`...
for clause in elaborate::elaborate(
cx,
cx.implied_const_bounds(alias_ty.def_id)
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.host)),
) {
candidates.extend(Self::probe_and_match_goal_against_assumption(
ecx,
CandidateSource::AliasBound,
goal,
clause,
|ecx| {
// Const conditions must hold for the implied const bound to hold.
ecx.add_goals(
GoalSource::Misc,
cx.const_conditions(alias_ty.def_id)
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| {
goal.with(
cx,
trait_ref.to_host_effect_clause(cx, goal.predicate.host),
)
}),
);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
},
));
}

candidates
}

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ where
}
}

fn consider_additional_alias_assumptions(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
_alias_ty: ty::AliasTy<I>,
) -> Vec<Candidate<I>> {
vec![]
}

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, NormalizesTo<I>>,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ where
self.def_id()
}

fn consider_additional_alias_assumptions(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
_alias_ty: ty::AliasTy<I>,
) -> Vec<Candidate<I>> {
vec![]
}

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, TraitPredicate<I>>,
Expand Down
Loading

0 comments on commit 97ae1df

Please sign in to comment.