提交 0986d645 编写于 作者: B bors

Auto merge of #32236 - alexcrichton:better-compile-intrinsics, r=arielb1

rustc: Improve compile time of platform intrinsics

This commit improves the compile time of `rustc_platform_intrinsics` from 23s to
3.6s if compiling with `-O` and from 77s to 17s if compiling with `-O -g`. The
compiled rlib size also drops from 3.1M to 1.2M.

The wins here were gained by removing the destructors associated with `Type` by
removing the internal `Box` and `Vec` indirections. These destructors meant that
a lot of landing pads and extra code were generated to manage the runtime
representations. Instead everything can basically be statically computed and
shoved into rodata, so all we need is a giant string compare to lookup what's
what.

Closes #28273
......@@ -117,7 +117,10 @@ class Void(Type):
Type.__init__(self, 0)
def compiler_ctor(self):
return 'void()'
return '::VOID'
def compiler_ctor_ref(self):
return '&' + self.compiler_ctor()
def rust_name(self):
return '()'
......@@ -163,10 +166,12 @@ class Signed(Number):
def compiler_ctor(self):
if self._llvm_bitwidth is None:
return 'i({})'.format(self.bitwidth())
return '::I{}'.format(self.bitwidth())
else:
return 'i_({}, {})'.format(self.bitwidth(),
self._llvm_bitwidth)
return '::I{}_{}'.format(self.bitwidth(), self._llvm_bitwidth)
def compiler_ctor_ref(self):
return '&' + self.compiler_ctor()
def llvm_name(self):
bw = self._llvm_bitwidth or self.bitwidth()
......@@ -182,10 +187,12 @@ class Unsigned(Number):
def compiler_ctor(self):
if self._llvm_bitwidth is None:
return 'u({})'.format(self.bitwidth())
return '::U{}'.format(self.bitwidth())
else:
return 'u_({}, {})'.format(self.bitwidth(),
self._llvm_bitwidth)
return '::U{}_{}'.format(self.bitwidth(), self._llvm_bitwidth)
def compiler_ctor_ref(self):
return '&' + self.compiler_ctor()
def llvm_name(self):
bw = self._llvm_bitwidth or self.bitwidth()
......@@ -200,7 +207,10 @@ class Float(Number):
Number.__init__(self, bitwidth)
def compiler_ctor(self):
return 'f({})'.format(self.bitwidth())
return '::F{}'.format(self.bitwidth())
def compiler_ctor_ref(self):
return '&' + self.compiler_ctor()
def llvm_name(self):
return 'f{}'.format(self.bitwidth())
......@@ -244,12 +254,16 @@ class Vector(Type):
def compiler_ctor(self):
if self._bitcast is None:
return 'v({}, {})'.format(self._elem.compiler_ctor(),
self._length)
return '{}x{}'.format(self._elem.compiler_ctor(),
self._length)
else:
return 'v_({}, {}, {})'.format(self._elem.compiler_ctor(),
self._bitcast.compiler_ctor(),
self._length)
return '{}x{}_{}'.format(self._elem.compiler_ctor(),
self._length,
self._bitcast.compiler_ctor()
.replace('::', ''))
def compiler_ctor_ref(self):
return '&' + self.compiler_ctor()
def rust_name(self):
return '{}x{}'.format(self._elem.rust_name(), self._length)
......@@ -284,10 +298,14 @@ class Pointer(Type):
if self._llvm_elem is None:
llvm_elem = 'None'
else:
llvm_elem = 'Some({})'.format(self._llvm_elem.compiler_ctor())
return 'p({}, {}, {})'.format('true' if self._const else 'false',
self._elem.compiler_ctor(),
llvm_elem)
llvm_elem = 'Some({})'.format(self._llvm_elem.compiler_ctor_ref())
return 'Type::Pointer({}, {}, {})'.format(self._elem.compiler_ctor_ref(),
llvm_elem,
'true' if self._const else 'false')
def compiler_ctor_ref(self):
return "{{ static PTR: Type = {}; &PTR }}".format(self.compiler_ctor())
def rust_name(self):
return '*{} {}'.format('const' if self._const else 'mut',
......@@ -322,8 +340,14 @@ class Aggregate(Type):
raise NotImplementedError()
def compiler_ctor(self):
return 'agg({}, vec![{}])'.format('true' if self._flatten else 'false',
', '.join(elem.compiler_ctor() for elem in self._elems))
parts = "{{ static PARTS: [&'static Type; {}] = [{}]; &PARTS }}"
elems = ', '.join(elem.compiler_ctor_ref() for elem in self._elems)
parts = parts.format(len(self._elems), elems)
return 'Type::Aggregate({}, {})'.format('true' if self._flatten else 'false',
parts)
def compiler_ctor_ref(self):
return "{{ static AGG: Type = {}; &AGG }}".format(self.compiler_ctor())
def rust_name(self):
return '({})'.format(', '.join(elem.rust_name() for elem in self._elems))
......@@ -518,10 +542,10 @@ class MonomorphicIntrinsic(object):
return self._platform.platform().intrinsic_prefix() + self.intrinsic_suffix()
def compiler_args(self):
return ', '.join(arg.compiler_ctor() for arg in self._args_raw)
return ', '.join(arg.compiler_ctor_ref() for arg in self._args_raw)
def compiler_ret(self):
return self._ret_raw.compiler_ctor()
return self._ret_raw.compiler_ctor_ref()
def compiler_signature(self):
return '({}) -> {}'.format(self.compiler_args(), self.compiler_ret())
......@@ -733,7 +757,7 @@ class CompilerDefs(object):
#![allow(unused_imports)]
use {{Intrinsic, i, i_, u, u_, f, v, v_, agg, p, void}};
use {{Intrinsic, Type}};
use IntrinsicDef::Named;
use rustc::middle::ty::TyCtxt;
......@@ -747,10 +771,11 @@ pub fn find<'tcx>(_tcx: &TyCtxt<'tcx>, name: &str) -> Option<Intrinsic> {{
def render(self, mono):
return '''\
"{}" => Intrinsic {{
inputs: vec![{}],
inputs: {{ static INPUTS: [&'static Type; {}] = [{}]; &INPUTS }},
output: {},
definition: Named("{}")
}},'''.format(mono.intrinsic_suffix(),
len(mono._args_raw),
mono.compiler_args(),
mono.compiler_ret(),
mono.llvm_name())
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -14,6 +14,7 @@
#![crate_type = "rlib"]
#![feature(staged_api, rustc_private)]
#![cfg_attr(not(stage0), deny(warnings))]
#![allow(bad_style)]
extern crate rustc_llvm as llvm;
extern crate rustc;
......@@ -21,8 +22,8 @@
use rustc::middle::ty::TyCtxt;
pub struct Intrinsic {
pub inputs: Vec<Type>,
pub output: Type,
pub inputs: &'static [&'static Type],
pub output: &'static Type,
pub definition: IntrinsicDef,
}
......@@ -32,34 +33,69 @@ pub enum Type {
Void,
Integer(/* signed */ bool, u8, /* llvm width */ u8),
Float(u8),
Pointer(Box<Type>, Option<Box<Type>>, /* const */ bool),
Vector(Box<Type>, Option<Box<Type>>, u8),
Aggregate(bool, Vec<Type>),
Pointer(&'static Type, Option<&'static Type>, /* const */ bool),
Vector(&'static Type, Option<&'static Type>, u8),
Aggregate(bool, &'static [&'static Type]),
}
pub enum IntrinsicDef {
Named(&'static str),
}
fn i(width: u8) -> Type { Type::Integer(true, width, width) }
fn i_(width: u8, llvm_width: u8) -> Type { Type::Integer(true, width, llvm_width) }
fn u(width: u8) -> Type { Type::Integer(false, width, width) }
#[allow(dead_code)]
fn u_(width: u8, llvm_width: u8) -> Type { Type::Integer(false, width, llvm_width) }
fn f(width: u8) -> Type { Type::Float(width) }
fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), None, length) }
fn v_(x: Type, bitcast: Type, length: u8) -> Type {
Type::Vector(Box::new(x), Some(Box::new(bitcast)), length)
}
fn agg(flatten: bool, types: Vec<Type>) -> Type {
Type::Aggregate(flatten, types)
}
fn p(const_: bool, elem: Type, llvm_elem: Option<Type>) -> Type {
Type::Pointer(Box::new(elem), llvm_elem.map(Box::new), const_)
}
fn void() -> Type {
Type::Void
}
static I8: Type = Type::Integer(true, 8, 8);
static I16: Type = Type::Integer(true, 16, 16);
static I32: Type = Type::Integer(true, 32, 32);
static I64: Type = Type::Integer(true, 64, 64);
static U8: Type = Type::Integer(false, 8, 8);
static U16: Type = Type::Integer(false, 16, 16);
static U32: Type = Type::Integer(false, 32, 32);
static U64: Type = Type::Integer(false, 64, 64);
static F32: Type = Type::Float(32);
static F64: Type = Type::Float(64);
static I32_8: Type = Type::Integer(true, 32, 8);
static I8x8: Type = Type::Vector(&I8, None, 8);
static U8x8: Type = Type::Vector(&U8, None, 8);
static I8x16: Type = Type::Vector(&I8, None, 16);
static U8x16: Type = Type::Vector(&U8, None, 16);
static I8x32: Type = Type::Vector(&I8, None, 32);
static U8x32: Type = Type::Vector(&U8, None, 32);
static I16x4: Type = Type::Vector(&I16, None, 4);
static U16x4: Type = Type::Vector(&U16, None, 4);
static I16x8: Type = Type::Vector(&I16, None, 8);
static U16x8: Type = Type::Vector(&U16, None, 8);
static I16x16: Type = Type::Vector(&I16, None, 16);
static U16x16: Type = Type::Vector(&U16, None, 16);
static I32x2: Type = Type::Vector(&I32, None, 2);
static U32x2: Type = Type::Vector(&U32, None, 2);
static I32x4: Type = Type::Vector(&I32, None, 4);
static U32x4: Type = Type::Vector(&U32, None, 4);
static I32x8: Type = Type::Vector(&I32, None, 8);
static U32x8: Type = Type::Vector(&U32, None, 8);
static I64x1: Type = Type::Vector(&I64, None, 1);
static U64x1: Type = Type::Vector(&U64, None, 1);
static I64x2: Type = Type::Vector(&I64, None, 2);
static U64x2: Type = Type::Vector(&U64, None, 2);
static I64x4: Type = Type::Vector(&I64, None, 4);
static U64x4: Type = Type::Vector(&U64, None, 4);
static F32x2: Type = Type::Vector(&F32, None, 2);
static F32x4: Type = Type::Vector(&F32, None, 4);
static F32x8: Type = Type::Vector(&F32, None, 8);
static F64x1: Type = Type::Vector(&F64, None, 1);
static F64x2: Type = Type::Vector(&F64, None, 2);
static F64x4: Type = Type::Vector(&F64, None, 4);
static I32x4_F32: Type = Type::Vector(&I32, Some(&F32), 4);
static I32x8_F32: Type = Type::Vector(&I32, Some(&F32), 8);
static I64x2_F64: Type = Type::Vector(&I64, Some(&F64), 2);
static I64x4_F64: Type = Type::Vector(&I64, Some(&F64), 4);
static VOID: Type = Type::Void;
mod x86;
mod arm;
......
......@@ -955,7 +955,7 @@ fn modify_as_needed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
};
match intr.output {
match *intr.output {
intrinsics::Type::Aggregate(flatten, ref elems) => {
// the output is a tuple so we need to munge it properly
assert!(!flatten);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册