]> git.lizzy.rs Git - rust.git/blobdiff - src/base.rs
Rustup to rustc 1.54.0-nightly (881c1ac40 2021-05-08)
[rust.git] / src / base.rs
index 8b7a7caade54d56e02db9ea81e60eb315401a915..3ec5c14ff17a2d8308657936aa5c21f15cfc6160 100644 (file)
@@ -6,9 +6,14 @@
 use rustc_middle::ty::layout::FnAbiExt;
 use rustc_target::abi::call::FnAbi;
 
+use crate::constant::ConstantCx;
 use crate::prelude::*;
 
-pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: Instance<'tcx>) {
+pub(crate) fn codegen_fn<'tcx>(
+    cx: &mut crate::CodegenCx<'tcx>,
+    module: &mut dyn Module,
+    instance: Instance<'tcx>,
+) {
     let tcx = cx.tcx;
 
     let _inst_guard =
@@ -18,9 +23,9 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     let mir = tcx.instance_mir(instance.def);
 
     // Declare function
-    let name = tcx.symbol_name(instance).name.to_string();
-    let sig = get_function_sig(tcx, cx.module.isa().triple(), instance);
-    let func_id = cx.module.declare_function(&name, Linkage::Local, &sig).unwrap();
+    let symbol_name = tcx.symbol_name(instance);
+    let sig = get_function_sig(tcx, module.isa().triple(), instance);
+    let func_id = module.declare_function(symbol_name.name, Linkage::Local, &sig).unwrap();
 
     cx.cached_context.clear();
 
@@ -39,15 +44,19 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
         (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
 
     // Make FunctionCx
-    let pointer_type = cx.module.target_config().pointer_type();
+    let pointer_type = module.target_config().pointer_type();
     let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
 
     let mut fx = FunctionCx {
         cx,
+        module,
         tcx,
         pointer_type,
+        vtables: FxHashMap::default(),
+        constants_cx: ConstantCx::new(),
 
         instance,
+        symbol_name,
         mir,
         fn_abi: Some(FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
 
@@ -90,6 +99,8 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     let source_info_set = fx.source_info_set;
     let local_map = fx.local_map;
 
+    fx.constants_cx.finalize(fx.tcx, &mut *fx.module);
+
     // Store function in context
     let context = &mut cx.cached_context;
     context.func = func;
@@ -108,8 +119,8 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     // instruction, which doesn't have an encoding.
     context.compute_cfg();
     context.compute_domtree();
-    context.eliminate_unreachable_code(cx.module.isa()).unwrap();
-    context.dce(cx.module.isa()).unwrap();
+    context.eliminate_unreachable_code(module.isa()).unwrap();
+    context.dce(module.isa()).unwrap();
     // Some Cranelift optimizations expect the domtree to not yet be computed and as such don't
     // invalidate it when it would change.
     context.domtree.clear();
@@ -117,7 +128,6 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
 
     // Define function
-    let module = &mut cx.module;
     tcx.sess.time("define function", || {
         module
             .define_function(func_id, context, &mut NullTrapSink {}, &mut NullStackMapSink {})
@@ -128,7 +138,7 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     crate::pretty_clif::write_clif_file(
         tcx,
         "opt",
-        Some(cx.module.isa()),
+        Some(module.isa()),
         instance,
         &context,
         &clif_comments,
@@ -137,13 +147,13 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
     if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
         crate::pretty_clif::write_ir_file(
             tcx,
-            &format!("{}.vcode", tcx.symbol_name(instance).name),
+            || format!("{}.vcode", tcx.symbol_name(instance).name),
             |file| file.write_all(disasm.as_bytes()),
         )
     }
 
     // Define debuginfo for function
-    let isa = cx.module.isa();
+    let isa = module.isa();
     let debug_context = &mut cx.debug_context;
     let unwind_context = &mut cx.unwind_context;
     tcx.sess.time("generate debug info", || {
@@ -151,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
             debug_context.define_function(
                 instance,
                 func_id,
-                &name,
+                symbol_name.name,
                 isa,
                 context,
                 &source_info_set,
@@ -648,7 +658,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
                         // FIXME use emit_small_memset where possible
                         let addr = lval.to_ptr().get_addr(fx);
                         let val = operand.load_scalar(fx);
-                        fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times);
+                        fx.bcx.call_memset(fx.module.target_config(), addr, val, times);
                     } else {
                         let loop_block = fx.bcx.create_block();
                         let loop_block2 = fx.bcx.create_block();
@@ -734,85 +744,15 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
         | StatementKind::AscribeUserType(..) => {}
 
         StatementKind::LlvmInlineAsm(asm) => {
-            use rustc_span::symbol::Symbol;
-            let LlvmInlineAsm { asm, outputs, inputs } = &**asm;
-            let rustc_hir::LlvmInlineAsmInner {
-                asm: asm_code,         // Name
-                outputs: output_names, // Vec<LlvmInlineAsmOutput>
-                inputs: input_names,   // Vec<Name>
-                clobbers,              // Vec<Name>
-                volatile,              // bool
-                alignstack,            // bool
-                dialect: _,
-                asm_str_style: _,
-            } = asm;
-            match asm_code.as_str().trim() {
+            match asm.asm.asm.as_str().trim() {
                 "" => {
                     // Black box
                 }
-                "mov %rbx, %rsi\n                  cpuid\n                  xchg %rbx, %rsi" => {
-                    assert_eq!(input_names, &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]);
-                    assert_eq!(output_names.len(), 4);
-                    for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]).iter().enumerate() {
-                        assert_eq!(&output_names[i].constraint.as_str(), c);
-                        assert!(!output_names[i].is_rw);
-                        assert!(!output_names[i].is_indirect);
-                    }
-
-                    assert_eq!(clobbers, &[]);
-
-                    assert!(!volatile);
-                    assert!(!alignstack);
-
-                    assert_eq!(inputs.len(), 2);
-                    let leaf = codegen_operand(fx, &inputs[0].1).load_scalar(fx); // %eax
-                    let subleaf = codegen_operand(fx, &inputs[1].1).load_scalar(fx); // %ecx
-
-                    let (eax, ebx, ecx, edx) =
-                        crate::intrinsics::codegen_cpuid_call(fx, leaf, subleaf);
-
-                    assert_eq!(outputs.len(), 4);
-                    codegen_place(fx, outputs[0])
-                        .write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
-                    codegen_place(fx, outputs[1])
-                        .write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
-                    codegen_place(fx, outputs[2])
-                        .write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
-                    codegen_place(fx, outputs[3])
-                        .write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
-                }
-                "xgetbv" => {
-                    assert_eq!(input_names, &[Symbol::intern("{ecx}")]);
-
-                    assert_eq!(output_names.len(), 2);
-                    for (i, c) in (&["={eax}", "={edx}"]).iter().enumerate() {
-                        assert_eq!(&output_names[i].constraint.as_str(), c);
-                        assert!(!output_names[i].is_rw);
-                        assert!(!output_names[i].is_indirect);
-                    }
-
-                    assert_eq!(clobbers, &[]);
-
-                    assert!(!volatile);
-                    assert!(!alignstack);
-
-                    crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported");
-                }
-                // ___chkstk, ___chkstk_ms and __alloca are only used on Windows
-                _ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") => {
-                    crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
-                }
-                _ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => {
-                    crate::trap::trap_unimplemented(fx, "Alloca is not supported");
-                }
-                // Used in sys::windows::abort_internal
-                "int $$0x29" => {
-                    crate::trap::trap_unimplemented(fx, "Windows abort");
-                }
-                _ => fx
-                    .tcx
-                    .sess
-                    .span_fatal(stmt.source_info.span, "Inline assembly is not supported"),
+                _ => fx.tcx.sess.span_fatal(
+                    stmt.source_info.span,
+                    "Legacy `llvm_asm!` inline assembly is not supported. \
+                    Try using the new `asm!` instead.",
+                ),
             }
         }
         StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"),
@@ -828,7 +768,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
             let elem_size: u64 = pointee.size.bytes();
             let bytes =
                 if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
-            fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes);
+            fx.bcx.call_memcpy(fx.module.target_config(), dst, src, bytes);
         }
     }
 }