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
This commit is contained in:
commit
0986d645b9
6 changed files with 2802 additions and 2741 deletions
|
|
@ -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())
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -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 @@ extern crate rustc;
|
|||
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;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -955,7 +955,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue