about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorTim Diekmann <tim.diekmann@3dvision.de>2020-10-25 16:32:28 +0100
committerTim Diekmann <tim.diekmann@3dvision.de>2020-10-25 16:32:28 +0100
commit06e4497a04615ad95dff4240ca9980f19ed364ad (patch)
tree123a17d04628e05bb2448d1d3e3f11e60f240304 /compiler/rustc_codegen_ssa/src
parent693a2bf18b7090202784f561de3dfca45c4f79be (diff)
parentf392479de6b003e72f93cb8f9955b3cf4135c2cd (diff)
downloadrust-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.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs24
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/intrinsic.rs4
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;