diff options
| author | Tim Diekmann <tim.diekmann@3dvision.de> | 2020-10-25 16:32:28 +0100 |
|---|---|---|
| committer | Tim Diekmann <tim.diekmann@3dvision.de> | 2020-10-25 16:32:28 +0100 |
| commit | 06e4497a04615ad95dff4240ca9980f19ed364ad (patch) | |
| tree | 123a17d04628e05bb2448d1d3e3f11e60f240304 /compiler/rustc_codegen_ssa/src | |
| parent | 693a2bf18b7090202784f561de3dfca45c4f79be (diff) | |
| parent | f392479de6b003e72f93cb8f9955b3cf4135c2cd (diff) | |
| download | rust-06e4497a04615ad95dff4240ca9980f19ed364ad.tar.gz rust-06e4497a04615ad95dff4240ca9980f19ed364ad.zip | |
Merge remote-tracking branch 'upstream/master' into box-alloc
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/builder.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 4 |
6 files changed, 44 insertions, 20 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a051ae25a9c..bec0a84cac0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -163,7 +163,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { target <= self.bb && target.start_location().is_predecessor_of(self.bb.start_location(), mir) }) { - bx.sideeffect(); + bx.sideeffect(false); } } } @@ -964,7 +964,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::TerminatorKind::Goto { target } => { - helper.maybe_sideeffect(self.mir, &mut bx, &[target]); + if bb == target { + // This is an unconditional branch back to this same basic + // block. That means we have something like a `loop {}` + // statement. Currently LLVM miscompiles this because it + // assumes forward progress. We want to prevent this in all + // cases, but that has a fairly high cost to compile times + // currently. Instead, try to handle this specific case + // which comes up commonly in practice (e.g., in embedded + // code). + // + // The `true` here means we insert side effects regardless + // of -Zinsert-sideeffect being passed on unconditional + // branching to the same basic block. + bx.sideeffect(true); + } else { + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); + } helper.funclet_br(self, &mut bx, target); } diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index a2ad27b925c..4811adea9ec 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -10,19 +10,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Coverage { kind, code_region } = coverage; match kind { CoverageKind::Counter { function_source_hash, id } => { - bx.add_counter_region(self.instance, function_source_hash, id, code_region); + if bx.add_counter_region(self.instance, function_source_hash, id, code_region) { + let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id()); - let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id()); - - let fn_name = bx.create_pgo_func_name_var(self.instance); - let hash = bx.const_u64(function_source_hash); - let num_counters = bx.const_u32(coverageinfo.num_counters); - let id = bx.const_u32(u32::from(id)); - debug!( - "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})", - fn_name, hash, num_counters, id, - ); - bx.instrprof_increment(fn_name, hash, num_counters, id); + let fn_name = bx.create_pgo_func_name_var(self.instance); + let hash = bx.const_u64(function_source_hash); + let num_counters = bx.const_u32(coverageinfo.num_counters); + let id = bx.const_u32(u32::from(id)); + debug!( + "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})", + fn_name, hash, num_counters, id, + ); + bx.instrprof_increment(fn_name, hash, num_counters, id); + } } CoverageKind::Expression { id, lhs, op, rhs } => { bx.add_counter_expression_region(self.instance, id, lhs, op, rhs, code_region); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 64d456fb7aa..bff263567bf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -153,7 +153,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx.set_personality_fn(cx.eh_personality()); } - bx.sideeffect(); + bx.sideeffect(false); let cleanup_kinds = analyze::cleanup_kinds(&mir); // Allocate a `Block` for every basic block, except diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 0b8289a8dd9..d5bd2780388 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -45,7 +45,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn build_sibling_block(&self, name: &str) -> Self; fn cx(&self) -> &Self::CodegenCx; fn llbb(&self) -> Self::BasicBlock; - fn set_span(&self, span: Span); + fn set_span(&mut self, span: Span); fn position_at_end(&mut self, llbb: Self::BasicBlock); fn ret_void(&mut self); diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index b74e4e45901..3b1654f3ad4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -9,14 +9,18 @@ pub trait CoverageInfoMethods: BackendTypes { pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value; + /// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage` + /// is not enabled (a coverage map is not being generated). fn add_counter_region( &mut self, instance: Instance<'tcx>, function_source_hash: u64, id: CounterValueReference, region: CodeRegion, - ); + ) -> bool; + /// Returns true if the expression was added to the coverage map; false if + /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). fn add_counter_expression_region( &mut self, instance: Instance<'tcx>, @@ -25,7 +29,9 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { op: Op, rhs: ExpressionOperandId, region: CodeRegion, - ); + ) -> bool; - fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion); + /// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage` + /// is not enabled (a coverage map is not being generated). + fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool; } diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index ccd294d92b2..ac3c99f9c90 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -20,7 +20,9 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes { fn abort(&mut self); fn assume(&mut self, val: Self::Value); fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; - fn sideeffect(&mut self); + /// Normally, sideeffect is only emitted if -Zinsert-sideeffect is passed; + /// in some cases though we want to emit it regardless. + fn sideeffect(&mut self, unconditional: bool); /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in /// Rust defined C-variadic functions. fn va_start(&mut self, val: Self::Value) -> Self::Value; |
