Skip to content

Commit 15a5009

Browse files
committed
Don't use llvm intrinsic names in cg_ssa
1 parent 8698f5c commit 15a5009

File tree

9 files changed

+113
-108
lines changed

9 files changed

+113
-108
lines changed

src/librustc_codegen_llvm/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
470470
}
471471
}
472472

473-
impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
474-
fn get_intrinsic(&self, key: &str) -> &'b Value {
473+
impl CodegenCx<'b, 'tcx> {
474+
crate fn get_intrinsic(&self, key: &str) -> &'b Value {
475475
if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
476476
return v;
477477
}

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,95 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
763763
}
764764
}
765765
}
766+
767+
fn abort(&mut self) {
768+
let fnname = self.cx().get_intrinsic(&("llvm.trap"));
769+
self.call(fnname, &[], None);
770+
}
771+
772+
fn assume(&mut self, val: Self::Value) {
773+
let assume_intrinsic = self.cx().get_intrinsic("llvm.assume");
774+
self.call(assume_intrinsic, &[val], None);
775+
}
776+
777+
fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value {
778+
let expect = self.cx().get_intrinsic(&"llvm.expect.i1");
779+
self.call(expect, &[cond, self.cx().const_bool(expected)], None)
780+
}
781+
782+
fn call_overflow_intrinsic(
783+
&mut self,
784+
oop: OverflowOp,
785+
ty: Ty,
786+
lhs: Self::Value,
787+
rhs: Self::Value,
788+
) -> (Self::Value, Self::Value) {
789+
use syntax::ast::IntTy::*;
790+
use syntax::ast::UintTy::*;
791+
use rustc::ty::{Int, Uint};
792+
793+
let new_sty = match ty.sty {
794+
Int(Isize) => Int(self.tcx().sess.target.isize_ty),
795+
Uint(Usize) => Uint(self.tcx().sess.target.usize_ty),
796+
ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
797+
_ => panic!("tried to get overflow intrinsic for op applied to non-int type")
798+
};
799+
800+
let name = match oop {
801+
OverflowOp::Add => match new_sty {
802+
Int(I8) => "llvm.sadd.with.overflow.i8",
803+
Int(I16) => "llvm.sadd.with.overflow.i16",
804+
Int(I32) => "llvm.sadd.with.overflow.i32",
805+
Int(I64) => "llvm.sadd.with.overflow.i64",
806+
Int(I128) => "llvm.sadd.with.overflow.i128",
807+
808+
Uint(U8) => "llvm.uadd.with.overflow.i8",
809+
Uint(U16) => "llvm.uadd.with.overflow.i16",
810+
Uint(U32) => "llvm.uadd.with.overflow.i32",
811+
Uint(U64) => "llvm.uadd.with.overflow.i64",
812+
Uint(U128) => "llvm.uadd.with.overflow.i128",
813+
814+
_ => unreachable!(),
815+
},
816+
OverflowOp::Sub => match new_sty {
817+
Int(I8) => "llvm.ssub.with.overflow.i8",
818+
Int(I16) => "llvm.ssub.with.overflow.i16",
819+
Int(I32) => "llvm.ssub.with.overflow.i32",
820+
Int(I64) => "llvm.ssub.with.overflow.i64",
821+
Int(I128) => "llvm.ssub.with.overflow.i128",
822+
823+
Uint(U8) => "llvm.usub.with.overflow.i8",
824+
Uint(U16) => "llvm.usub.with.overflow.i16",
825+
Uint(U32) => "llvm.usub.with.overflow.i32",
826+
Uint(U64) => "llvm.usub.with.overflow.i64",
827+
Uint(U128) => "llvm.usub.with.overflow.i128",
828+
829+
_ => unreachable!(),
830+
},
831+
OverflowOp::Mul => match new_sty {
832+
Int(I8) => "llvm.smul.with.overflow.i8",
833+
Int(I16) => "llvm.smul.with.overflow.i16",
834+
Int(I32) => "llvm.smul.with.overflow.i32",
835+
Int(I64) => "llvm.smul.with.overflow.i64",
836+
Int(I128) => "llvm.smul.with.overflow.i128",
837+
838+
Uint(U8) => "llvm.umul.with.overflow.i8",
839+
Uint(U16) => "llvm.umul.with.overflow.i16",
840+
Uint(U32) => "llvm.umul.with.overflow.i32",
841+
Uint(U64) => "llvm.umul.with.overflow.i64",
842+
Uint(U128) => "llvm.umul.with.overflow.i128",
843+
844+
_ => unreachable!(),
845+
},
846+
};
847+
848+
let intrinsic = self.cx().get_intrinsic(&name);
849+
let res = self.call(intrinsic, &[lhs, rhs], None);
850+
(
851+
self.extract_value(res, 0),
852+
self.extract_value(res, 1),
853+
)
854+
}
766855
}
767856

768857
fn copy_intrinsic(

src/librustc_codegen_ssa/base.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,6 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
366366
sess.target.target.options.is_like_msvc
367367
}
368368

369-
pub fn call_assume<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
370-
bx: &mut Bx,
371-
val: Bx::Value
372-
) {
373-
let assume_intrinsic = bx.cx().get_intrinsic("llvm.assume");
374-
bx.call(assume_intrinsic, &[val], None);
375-
}
376-
377369
pub fn from_immediate<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
378370
bx: &mut Bx,
379371
val: Bx::Value

src/librustc_codegen_ssa/mir/block.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
195195
}
196196

197197
mir::TerminatorKind::Abort => {
198-
// Call core::intrinsics::abort()
199-
let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
200-
bx.call(fnname, &[], None);
198+
bx.abort();
201199
bx.unreachable();
202200
}
203201

@@ -364,8 +362,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
364362
}
365363

366364
// Pass the condition through llvm.expect for branch hinting.
367-
let expect = bx.cx().get_intrinsic(&"llvm.expect.i1");
368-
let cond = bx.call(expect, &[cond, bx.cx().const_bool(expected)], None);
365+
let cond = bx.expect(cond, expected);
369366

370367
// Create the failure block and the conditional branch to it.
371368
let lltarget = llblock(self, target);

src/librustc_codegen_ssa/mir/operand.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
484484
}
485485
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
486486
// the above error (or silence it under some conditions) will not cause UB
487-
let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
488-
bx.call(fnname, &[], None);
487+
bx.abort();
489488
// We've errored, so we don't have to produce working code.
490489
let layout = bx.cx().layout_of(ty);
491490
bx.load_operand(PlaceRef::new_sized(

src/librustc_codegen_ssa/mir/place.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
413413
// and compile-time agree on values
414414
// With floats that won't always be true
415415
// so we generate an abort
416-
let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
417-
bx.call(fnname, &[], None);
416+
bx.abort();
418417
let llval = bx.cx().const_undef(
419418
bx.cx().type_ptr_to(bx.cx().backend_type(layout))
420419
);

src/librustc_codegen_ssa/mir/rvalue.rs

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
337337
llval,
338338
ll_t_in_const
339339
);
340-
base::call_assume(&mut bx, cmp);
340+
bx.assume(cmp);
341341
}
342342
}
343343
}
@@ -693,11 +693,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
693693
mir::BinOp::Mul => OverflowOp::Mul,
694694
_ => unreachable!()
695695
};
696-
let intrinsic = get_overflow_intrinsic(oop, bx, input_ty);
697-
let res = bx.call(intrinsic, &[lhs, rhs], None);
698-
699-
(bx.extract_value(res, 0),
700-
bx.extract_value(res, 1))
696+
bx.call_overflow_intrinsic(oop, input_ty, lhs, rhs)
701697
}
702698
mir::BinOp::Shl | mir::BinOp::Shr => {
703699
let lhs_llty = bx.cx().val_ty(lhs);
@@ -744,80 +740,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
744740
}
745741
}
746742

747-
#[derive(Copy, Clone)]
748-
enum OverflowOp {
749-
Add, Sub, Mul
750-
}
751-
752-
fn get_overflow_intrinsic<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
753-
oop: OverflowOp,
754-
bx: &mut Bx,
755-
ty: Ty
756-
) -> Bx::Value {
757-
use syntax::ast::IntTy::*;
758-
use syntax::ast::UintTy::*;
759-
use rustc::ty::{Int, Uint};
760-
761-
let tcx = bx.tcx();
762-
763-
let new_sty = match ty.sty {
764-
Int(Isize) => Int(tcx.sess.target.isize_ty),
765-
Uint(Usize) => Uint(tcx.sess.target.usize_ty),
766-
ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
767-
_ => panic!("tried to get overflow intrinsic for op applied to non-int type")
768-
};
769-
770-
let name = match oop {
771-
OverflowOp::Add => match new_sty {
772-
Int(I8) => "llvm.sadd.with.overflow.i8",
773-
Int(I16) => "llvm.sadd.with.overflow.i16",
774-
Int(I32) => "llvm.sadd.with.overflow.i32",
775-
Int(I64) => "llvm.sadd.with.overflow.i64",
776-
Int(I128) => "llvm.sadd.with.overflow.i128",
777-
778-
Uint(U8) => "llvm.uadd.with.overflow.i8",
779-
Uint(U16) => "llvm.uadd.with.overflow.i16",
780-
Uint(U32) => "llvm.uadd.with.overflow.i32",
781-
Uint(U64) => "llvm.uadd.with.overflow.i64",
782-
Uint(U128) => "llvm.uadd.with.overflow.i128",
783-
784-
_ => unreachable!(),
785-
},
786-
OverflowOp::Sub => match new_sty {
787-
Int(I8) => "llvm.ssub.with.overflow.i8",
788-
Int(I16) => "llvm.ssub.with.overflow.i16",
789-
Int(I32) => "llvm.ssub.with.overflow.i32",
790-
Int(I64) => "llvm.ssub.with.overflow.i64",
791-
Int(I128) => "llvm.ssub.with.overflow.i128",
792-
793-
Uint(U8) => "llvm.usub.with.overflow.i8",
794-
Uint(U16) => "llvm.usub.with.overflow.i16",
795-
Uint(U32) => "llvm.usub.with.overflow.i32",
796-
Uint(U64) => "llvm.usub.with.overflow.i64",
797-
Uint(U128) => "llvm.usub.with.overflow.i128",
798-
799-
_ => unreachable!(),
800-
},
801-
OverflowOp::Mul => match new_sty {
802-
Int(I8) => "llvm.smul.with.overflow.i8",
803-
Int(I16) => "llvm.smul.with.overflow.i16",
804-
Int(I32) => "llvm.smul.with.overflow.i32",
805-
Int(I64) => "llvm.smul.with.overflow.i64",
806-
Int(I128) => "llvm.smul.with.overflow.i128",
807-
808-
Uint(U8) => "llvm.umul.with.overflow.i8",
809-
Uint(U16) => "llvm.umul.with.overflow.i16",
810-
Uint(U32) => "llvm.umul.with.overflow.i32",
811-
Uint(U64) => "llvm.umul.with.overflow.i64",
812-
Uint(U128) => "llvm.umul.with.overflow.i128",
813-
814-
_ => unreachable!(),
815-
},
816-
};
817-
818-
bx.cx().get_intrinsic(&name)
819-
}
820-
821743
fn cast_int_to_float<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
822744
bx: &mut Bx,
823745
signed: bool,

src/librustc_codegen_ssa/traits/intrinsic.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::Backend;
1211
use super::HasCodegen;
1312
use mir::operand::OperandRef;
1413
use rustc::ty::Ty;
1514
use rustc_target::abi::call::FnType;
1615
use syntax_pos::Span;
1716

17+
#[derive(Copy, Clone)]
18+
pub enum OverflowOp {
19+
Add, Sub, Mul
20+
}
21+
1822
pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> {
1923
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
2024
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
@@ -27,11 +31,16 @@ pub trait IntrinsicCallMethods<'tcx>: HasCodegen<'tcx> {
2731
llresult: Self::Value,
2832
span: Span,
2933
);
30-
}
3134

32-
pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
33-
fn get_intrinsic(&self, key: &str) -> Self::Value;
35+
fn abort(&mut self);
36+
fn assume(&mut self, val: Self::Value);
37+
fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value;
3438

35-
/// Declare any llvm intrinsics that you might need
36-
fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
39+
fn call_overflow_intrinsic(
40+
&mut self,
41+
oop: OverflowOp,
42+
ty: Ty,
43+
lhs: Self::Value,
44+
rhs: Self::Value,
45+
) -> (Self::Value, Self::Value);
3746
}

src/librustc_codegen_ssa/traits/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub use self::builder::BuilderMethods;
4444
pub use self::consts::ConstMethods;
4545
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
4646
pub use self::declare::{DeclareMethods, PreDefineMethods};
47-
pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods};
47+
pub use self::intrinsic::{IntrinsicCallMethods, OverflowOp};
4848
pub use self::misc::MiscMethods;
4949
pub use self::statics::StaticMethods;
5050
pub use self::type_::{
@@ -65,7 +65,6 @@ pub trait CodegenMethods<'tcx>:
6565
+ StaticMethods
6666
+ DebugInfoMethods<'tcx>
6767
+ AbiMethods<'tcx>
68-
+ IntrinsicDeclarationMethods<'tcx>
6968
+ DeclareMethods<'tcx>
7069
+ AsmMethods<'tcx>
7170
+ PreDefineMethods<'tcx>
@@ -80,7 +79,6 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
8079
+ StaticMethods
8180
+ DebugInfoMethods<'tcx>
8281
+ AbiMethods<'tcx>
83-
+ IntrinsicDeclarationMethods<'tcx>
8482
+ DeclareMethods<'tcx>
8583
+ AsmMethods<'tcx>
8684
+ PreDefineMethods<'tcx>

0 commit comments

Comments
 (0)