Skip to content

Commit 7b295ee

Browse files
committed
add NullOp::SizeOf and BinOp::Offset
1 parent 3bcd6fa commit 7b295ee

File tree

15 files changed

+74
-31
lines changed

15 files changed

+74
-31
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx>
315315
mir::Rvalue::Discriminant(ref lvalue) => {
316316
lvalue.hash_stable(hcx, hasher);
317317
}
318-
mir::Rvalue::Box(ty) => {
318+
mir::Rvalue::NullaryOp(op, ty) => {
319+
op.hash_stable(hcx, hasher);
319320
ty.hash_stable(hcx, hasher);
320321
}
321322
mir::Rvalue::Aggregate(ref kind, ref operands) => {
@@ -374,14 +375,19 @@ impl_stable_hash_for!(enum mir::BinOp {
374375
Le,
375376
Ne,
376377
Ge,
377-
Gt
378+
Gt,
379+
Offset
378380
});
379381

380382
impl_stable_hash_for!(enum mir::UnOp {
381383
Not,
382384
Neg
383385
});
384386

387+
impl_stable_hash_for!(enum mir::NullOp {
388+
Box,
389+
SizeOf
390+
});
385391

386392
impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
387393

src/librustc/mir/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,7 @@ pub enum Rvalue<'tcx> {
10461046
BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
10471047
CheckedBinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
10481048

1049+
NullaryOp(NullOp, Ty<'tcx>),
10491050
UnaryOp(UnOp, Operand<'tcx>),
10501051

10511052
/// Read the discriminant of an ADT.
@@ -1054,9 +1055,6 @@ pub enum Rvalue<'tcx> {
10541055
/// be defined to return, say, a 0) if ADT is not an enum.
10551056
Discriminant(Lvalue<'tcx>),
10561057

1057-
/// Creates an *uninitialized* Box
1058-
Box(Ty<'tcx>),
1059-
10601058
/// Create an aggregate value, like a tuple or struct. This is
10611059
/// only needed because we want to distinguish `dest = Foo { x:
10621060
/// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
@@ -1132,6 +1130,8 @@ pub enum BinOp {
11321130
Ge,
11331131
/// The `>` operator (greater than)
11341132
Gt,
1133+
/// The `ptr.offset` operator
1134+
Offset,
11351135
}
11361136

11371137
impl BinOp {
@@ -1144,6 +1144,14 @@ impl BinOp {
11441144
}
11451145
}
11461146

1147+
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
1148+
pub enum NullOp {
1149+
/// Return the size of a value of that type
1150+
SizeOf,
1151+
/// Create a new uninitialized box for a value of that type
1152+
Box,
1153+
}
1154+
11471155
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
11481156
pub enum UnOp {
11491157
/// The `!` operator for logical inversion
@@ -1167,7 +1175,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11671175
}
11681176
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
11691177
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
1170-
Box(ref t) => write!(fmt, "Box({:?})", t),
1178+
NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
11711179
Ref(_, borrow_kind, ref lv) => {
11721180
let kind_str = match borrow_kind {
11731181
BorrowKind::Shared => "",
@@ -1601,7 +1609,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
16011609
CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
16021610
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
16031611
Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
1604-
Box(ty) => Box(ty.fold_with(folder)),
1612+
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
16051613
Aggregate(ref kind, ref fields) => {
16061614
let kind = box match **kind {
16071615
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
@@ -1629,7 +1637,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
16291637
rhs.visit_with(visitor) || lhs.visit_with(visitor),
16301638
UnaryOp(_, ref val) => val.visit_with(visitor),
16311639
Discriminant(ref lval) => lval.visit_with(visitor),
1632-
Box(ty) => ty.visit_with(visitor),
1640+
NullaryOp(_, ty) => ty.visit_with(visitor),
16331641
Aggregate(ref kind, ref fields) => {
16341642
(match **kind {
16351643
AggregateKind::Array(ty) => ty.visit_with(visitor),

src/librustc/mir/tcx.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ impl<'tcx> Rvalue<'tcx> {
166166
let ty = op.ty(tcx, lhs_ty, rhs_ty);
167167
tcx.intern_tup(&[ty, tcx.types.bool], false)
168168
}
169-
Rvalue::UnaryOp(_, ref operand) => {
169+
Rvalue::UnaryOp(UnOp::Not, ref operand) |
170+
Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
170171
operand.ty(mir, tcx)
171172
}
172173
Rvalue::Discriminant(ref lval) => {
@@ -179,9 +180,8 @@ impl<'tcx> Rvalue<'tcx> {
179180
bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
180181
}
181182
}
182-
Rvalue::Box(t) => {
183-
tcx.mk_box(t)
184-
}
183+
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
184+
Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
185185
Rvalue::Aggregate(ref ak, ref ops) => {
186186
match **ak {
187187
AggregateKind::Array(ty) => {
@@ -227,7 +227,7 @@ impl<'tcx> BinOp {
227227
assert_eq!(lhs_ty, rhs_ty);
228228
lhs_ty
229229
}
230-
&BinOp::Shl | &BinOp::Shr => {
230+
&BinOp::Shl | &BinOp::Shr | &BinOp::Offset => {
231231
lhs_ty // lhs_ty can be != rhs_ty
232232
}
233233
&BinOp::Eq | &BinOp::Lt | &BinOp::Le |
@@ -270,7 +270,8 @@ impl BinOp {
270270
BinOp::Lt => hir::BinOp_::BiLt,
271271
BinOp::Gt => hir::BinOp_::BiGt,
272272
BinOp::Le => hir::BinOp_::BiLe,
273-
BinOp::Ge => hir::BinOp_::BiGe
273+
BinOp::Ge => hir::BinOp_::BiGe,
274+
BinOp::Offset => unreachable!()
274275
}
275276
}
276277
}

src/librustc/mir/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ macro_rules! make_mir_visitor {
509509
self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
510510
}
511511

512-
Rvalue::Box(ref $($mutability)* ty) => {
512+
Rvalue::NullaryOp(_op, ref $($mutability)* ty) => {
513513
self.visit_ty(ty);
514514
}
515515

src/librustc_borrowck/borrowck/mir/gather_moves.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,8 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
438438
Rvalue::Ref(..) |
439439
Rvalue::Discriminant(..) |
440440
Rvalue::Len(..) |
441-
Rvalue::Box(..) => {
441+
Rvalue::NullaryOp(NullOp::SizeOf, _) |
442+
Rvalue::NullaryOp(NullOp::Box, _) => {
442443
// This returns an rvalue with uninitialized contents. We can't
443444
// move out of it here because it is an rvalue - assignments always
444445
// completely initialize their lvalue.

src/librustc_mir/build/expr/as_rvalue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
9797
let value = this.hir.mirror(value);
9898
let result = this.temp(expr.ty, expr_span);
9999
// to start, malloc some memory of suitable type (thus far, uninitialized):
100-
this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
100+
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
101+
this.cfg.push_assign(block, source_info, &result, box_);
101102
this.in_scope(value_extents, block, |this| {
102103
// schedule a shallow free of that memory, lest we unwind:
103104
this.schedule_box_free(expr_span, value_extents, &result, value.ty);

src/librustc_mir/transform/erase_regions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
5353
Rvalue::CheckedBinaryOp(..) |
5454
Rvalue::UnaryOp(..) |
5555
Rvalue::Discriminant(..) |
56-
Rvalue::Box(..) |
56+
Rvalue::NullaryOp(..) |
5757
Rvalue::Aggregate(..) => {
5858
// These variants don't contain regions.
5959
}

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
595595
match *rvalue {
596596
Rvalue::Use(_) |
597597
Rvalue::Repeat(..) |
598-
Rvalue::UnaryOp(..) |
598+
Rvalue::UnaryOp(UnOp::Neg, _) |
599+
Rvalue::UnaryOp(UnOp::Not, _) |
600+
Rvalue::NullaryOp(NullOp::SizeOf, _) |
599601
Rvalue::CheckedBinaryOp(..) |
600602
Rvalue::Cast(CastKind::ReifyFnPointer, ..) |
601603
Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
@@ -703,7 +705,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
703705
if let ty::TyRawPtr(_) = lhs.ty(self.mir, self.tcx).sty {
704706
assert!(op == BinOp::Eq || op == BinOp::Ne ||
705707
op == BinOp::Le || op == BinOp::Lt ||
706-
op == BinOp::Ge || op == BinOp::Gt);
708+
op == BinOp::Ge || op == BinOp::Gt ||
709+
op == BinOp::Offset);
707710

708711
self.add(Qualif::NOT_CONST);
709712
if self.mode != Mode::Fn {
@@ -719,7 +722,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
719722
}
720723
}
721724

722-
Rvalue::Box(_) => {
725+
Rvalue::NullaryOp(NullOp::Box, _) => {
723726
self.add(Qualif::NOT_CONST);
724727
if self.mode != Mode::Fn {
725728
struct_span_err!(self.tcx.sess, self.span, E0010,

src/librustc_passes/mir_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
186186
Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp",
187187
Rvalue::UnaryOp(..) => "Rvalue::UnaryOp",
188188
Rvalue::Discriminant(..) => "Rvalue::Discriminant",
189-
Rvalue::Box(..) => "Rvalue::Box",
189+
Rvalue::NullaryOp(..) => "Rvalue::NullaryOp",
190190
Rvalue::Aggregate(ref kind, ref _operands) => {
191191
// AggregateKind is not distinguished by visit API, so
192192
// record it. (`super_rvalue` handles `_operands`.)

src/librustc_trans/collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
502502
_ => bug!(),
503503
}
504504
}
505-
mir::Rvalue::Box(..) => {
505+
mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => {
506506
let tcx = self.scx.tcx();
507507
let exchange_malloc_fn_def_id = tcx
508508
.lang_items

src/librustc_trans/glue.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
7676
let align = C_uint(bcx.ccx, align);
7777
return (size, align);
7878
}
79+
assert!(!info.is_null());
7980
match t.sty {
8081
ty::TyAdt(def, substs) => {
8182
let ccx = bcx.ccx;

src/librustc_trans/mir/constant.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,12 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
796796
Const::new(llval, operand.ty)
797797
}
798798

799+
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
800+
assert!(self.ccx.shared().type_is_sized(ty));
801+
let llval = C_uint(self.ccx, self.ccx.size_of(ty));
802+
Const::new(llval, tcx.types.usize)
803+
}
804+
799805
_ => span_bug!(span, "{:?} in constant", rvalue)
800806
};
801807

@@ -870,6 +876,7 @@ pub fn const_scalar_binop(op: mir::BinOp,
870876
llvm::LLVMConstICmp(cmp, lhs, rhs)
871877
}
872878
}
879+
mir::BinOp::Offset => unreachable!("BinOp::Offset in const-eval!")
873880
}
874881
}
875882
}

src/librustc_trans/mir/operand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
114114

115115
pub fn deref(self) -> LvalueRef<'tcx> {
116116
let projected_ty = self.ty.builtin_deref(true, ty::NoPreference)
117-
.unwrap().ty;
117+
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
118118
let (llptr, llextra) = match self.val {
119119
OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
120120
OperandValue::Pair(llptr, llextra) => (llptr, llextra),

src/librustc_trans/mir/rvalue.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
432432
})
433433
}
434434

435-
mir::Rvalue::Box(content_ty) => {
435+
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
436+
assert!(bcx.ccx.shared().type_is_sized(ty));
437+
let val = C_uint(bcx.ccx, bcx.ccx.size_of(ty));
438+
let tcx = bcx.tcx();
439+
(bcx, OperandRef {
440+
val: OperandValue::Immediate(val),
441+
ty: tcx.types.usize,
442+
})
443+
}
444+
445+
mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
436446
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
437447
let llty = type_of::type_of(bcx.ccx, content_ty);
438448
let llsize = machine::llsize_of(bcx.ccx, llty);
@@ -515,6 +525,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
515525
mir::BinOp::BitOr => bcx.or(lhs, rhs),
516526
mir::BinOp::BitAnd => bcx.and(lhs, rhs),
517527
mir::BinOp::BitXor => bcx.xor(lhs, rhs),
528+
mir::BinOp::Offset => bcx.inbounds_gep(lhs, &[rhs]),
518529
mir::BinOp::Shl => common::build_unchecked_lshift(bcx, lhs, rhs),
519530
mir::BinOp::Shr => common::build_unchecked_rshift(bcx, input_ty, lhs, rhs),
520531
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
@@ -660,7 +671,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
660671
mir::Rvalue::CheckedBinaryOp(..) |
661672
mir::Rvalue::UnaryOp(..) |
662673
mir::Rvalue::Discriminant(..) |
663-
mir::Rvalue::Box(..) |
674+
mir::Rvalue::NullaryOp(..) |
664675
mir::Rvalue::Use(..) => // (*)
665676
true,
666677
mir::Rvalue::Repeat(..) |

src/rustllvm/RustWrapper.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -781,11 +781,15 @@ extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
781781
extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
782782
RustStringRef Str) {
783783
RawRustStringOstream OS(Str);
784-
OS << "(";
785-
unwrap<llvm::Value>(V)->getType()->print(OS);
786-
OS << ":";
787-
unwrap<llvm::Value>(V)->print(OS);
788-
OS << ")";
784+
if (!V) {
785+
OS << "(null)";
786+
} else {
787+
OS << "(";
788+
unwrap<llvm::Value>(V)->getType()->print(OS);
789+
OS << ":";
790+
unwrap<llvm::Value>(V)->print(OS);
791+
OS << ")";
792+
}
789793
}
790794

791795
extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC,

0 commit comments

Comments
 (0)