Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add NullOp::SizeOf and BinOp::Offset
  • Loading branch information
arielb1 committed May 28, 2017
1 parent 3bcd6fa commit 7b295ee
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 31 deletions.
10 changes: 8 additions & 2 deletions src/librustc/ich/impls_mir.rs
Expand Up @@ -315,7 +315,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx>
mir::Rvalue::Discriminant(ref lvalue) => {
lvalue.hash_stable(hcx, hasher);
}
mir::Rvalue::Box(ty) => {
mir::Rvalue::NullaryOp(op, ty) => {
op.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
mir::Rvalue::Aggregate(ref kind, ref operands) => {
Expand Down Expand Up @@ -374,14 +375,19 @@ impl_stable_hash_for!(enum mir::BinOp {
Le,
Ne,
Ge,
Gt
Gt,
Offset
});

impl_stable_hash_for!(enum mir::UnOp {
Not,
Neg
});

impl_stable_hash_for!(enum mir::NullOp {
Box,
SizeOf
});

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

Expand Down
20 changes: 14 additions & 6 deletions src/librustc/mir/mod.rs
Expand Up @@ -1046,6 +1046,7 @@ pub enum Rvalue<'tcx> {
BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
CheckedBinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),

NullaryOp(NullOp, Ty<'tcx>),
UnaryOp(UnOp, Operand<'tcx>),

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

/// Creates an *uninitialized* Box
Box(Ty<'tcx>),

/// Create an aggregate value, like a tuple or struct. This is
/// only needed because we want to distinguish `dest = Foo { x:
/// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
Expand Down Expand Up @@ -1132,6 +1130,8 @@ pub enum BinOp {
Ge,
/// The `>` operator (greater than)
Gt,
/// The `ptr.offset` operator
Offset,
}

impl BinOp {
Expand All @@ -1144,6 +1144,14 @@ impl BinOp {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum NullOp {
/// Return the size of a value of that type
SizeOf,
/// Create a new uninitialized box for a value of that type
Box,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum UnOp {
/// The `!` operator for logical inversion
Expand All @@ -1167,7 +1175,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
Box(ref t) => write!(fmt, "Box({:?})", t),
NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
Ref(_, borrow_kind, ref lv) => {
let kind_str = match borrow_kind {
BorrowKind::Shared => "",
Expand Down Expand Up @@ -1601,7 +1609,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
Discriminant(ref lval) => Discriminant(lval.fold_with(folder)),
Box(ty) => Box(ty.fold_with(folder)),
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
Aggregate(ref kind, ref fields) => {
let kind = box match **kind {
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
Expand Down Expand Up @@ -1629,7 +1637,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
rhs.visit_with(visitor) || lhs.visit_with(visitor),
UnaryOp(_, ref val) => val.visit_with(visitor),
Discriminant(ref lval) => lval.visit_with(visitor),
Box(ty) => ty.visit_with(visitor),
NullaryOp(_, ty) => ty.visit_with(visitor),
Aggregate(ref kind, ref fields) => {
(match **kind {
AggregateKind::Array(ty) => ty.visit_with(visitor),
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/mir/tcx.rs
Expand Up @@ -166,7 +166,8 @@ impl<'tcx> Rvalue<'tcx> {
let ty = op.ty(tcx, lhs_ty, rhs_ty);
tcx.intern_tup(&[ty, tcx.types.bool], false)
}
Rvalue::UnaryOp(_, ref operand) => {
Rvalue::UnaryOp(UnOp::Not, ref operand) |
Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
operand.ty(mir, tcx)
}
Rvalue::Discriminant(ref lval) => {
Expand All @@ -179,9 +180,8 @@ impl<'tcx> Rvalue<'tcx> {
bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
}
}
Rvalue::Box(t) => {
tcx.mk_box(t)
}
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
Rvalue::Aggregate(ref ak, ref ops) => {
match **ak {
AggregateKind::Array(ty) => {
Expand Down Expand Up @@ -227,7 +227,7 @@ impl<'tcx> BinOp {
assert_eq!(lhs_ty, rhs_ty);
lhs_ty
}
&BinOp::Shl | &BinOp::Shr => {
&BinOp::Shl | &BinOp::Shr | &BinOp::Offset => {
lhs_ty // lhs_ty can be != rhs_ty
}
&BinOp::Eq | &BinOp::Lt | &BinOp::Le |
Expand Down Expand Up @@ -270,7 +270,8 @@ impl BinOp {
BinOp::Lt => hir::BinOp_::BiLt,
BinOp::Gt => hir::BinOp_::BiGt,
BinOp::Le => hir::BinOp_::BiLe,
BinOp::Ge => hir::BinOp_::BiGe
BinOp::Ge => hir::BinOp_::BiGe,
BinOp::Offset => unreachable!()
}
}
}
2 changes: 1 addition & 1 deletion src/librustc/mir/visit.rs
Expand Up @@ -509,7 +509,7 @@ macro_rules! make_mir_visitor {
self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
}

Rvalue::Box(ref $($mutability)* ty) => {
Rvalue::NullaryOp(_op, ref $($mutability)* ty) => {
self.visit_ty(ty);
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/gather_moves.rs
Expand Up @@ -438,7 +438,8 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
Rvalue::Ref(..) |
Rvalue::Discriminant(..) |
Rvalue::Len(..) |
Rvalue::Box(..) => {
Rvalue::NullaryOp(NullOp::SizeOf, _) |
Rvalue::NullaryOp(NullOp::Box, _) => {
// This returns an rvalue with uninitialized contents. We can't
// move out of it here because it is an rvalue - assignments always
// completely initialize their lvalue.
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -97,7 +97,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let value = this.hir.mirror(value);
let result = this.temp(expr.ty, expr_span);
// to start, malloc some memory of suitable type (thus far, uninitialized):
this.cfg.push_assign(block, source_info, &result, Rvalue::Box(value.ty));
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
this.cfg.push_assign(block, source_info, &result, box_);
this.in_scope(value_extents, block, |this| {
// schedule a shallow free of that memory, lest we unwind:
this.schedule_box_free(expr_span, value_extents, &result, value.ty);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/erase_regions.rs
Expand Up @@ -53,7 +53,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
Rvalue::CheckedBinaryOp(..) |
Rvalue::UnaryOp(..) |
Rvalue::Discriminant(..) |
Rvalue::Box(..) |
Rvalue::NullaryOp(..) |
Rvalue::Aggregate(..) => {
// These variants don't contain regions.
}
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -595,7 +595,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
match *rvalue {
Rvalue::Use(_) |
Rvalue::Repeat(..) |
Rvalue::UnaryOp(..) |
Rvalue::UnaryOp(UnOp::Neg, _) |
Rvalue::UnaryOp(UnOp::Not, _) |
Rvalue::NullaryOp(NullOp::SizeOf, _) |
Rvalue::CheckedBinaryOp(..) |
Rvalue::Cast(CastKind::ReifyFnPointer, ..) |
Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
Expand Down Expand Up @@ -703,7 +705,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if let ty::TyRawPtr(_) = lhs.ty(self.mir, self.tcx).sty {
assert!(op == BinOp::Eq || op == BinOp::Ne ||
op == BinOp::Le || op == BinOp::Lt ||
op == BinOp::Ge || op == BinOp::Gt);
op == BinOp::Ge || op == BinOp::Gt ||
op == BinOp::Offset);

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

Rvalue::Box(_) => {
Rvalue::NullaryOp(NullOp::Box, _) => {
self.add(Qualif::NOT_CONST);
if self.mode != Mode::Fn {
struct_span_err!(self.tcx.sess, self.span, E0010,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_passes/mir_stats.rs
Expand Up @@ -186,7 +186,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp",
Rvalue::UnaryOp(..) => "Rvalue::UnaryOp",
Rvalue::Discriminant(..) => "Rvalue::Discriminant",
Rvalue::Box(..) => "Rvalue::Box",
Rvalue::NullaryOp(..) => "Rvalue::NullaryOp",
Rvalue::Aggregate(ref kind, ref _operands) => {
// AggregateKind is not distinguished by visit API, so
// record it. (`super_rvalue` handles `_operands`.)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/collector.rs
Expand Up @@ -502,7 +502,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
_ => bug!(),
}
}
mir::Rvalue::Box(..) => {
mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => {
let tcx = self.scx.tcx();
let exchange_malloc_fn_def_id = tcx
.lang_items
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/glue.rs
Expand Up @@ -76,6 +76,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
let align = C_uint(bcx.ccx, align);
return (size, align);
}
assert!(!info.is_null());
match t.sty {
ty::TyAdt(def, substs) => {
let ccx = bcx.ccx;
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_trans/mir/constant.rs
Expand Up @@ -796,6 +796,12 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
Const::new(llval, operand.ty)
}

mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
assert!(self.ccx.shared().type_is_sized(ty));
let llval = C_uint(self.ccx, self.ccx.size_of(ty));
Const::new(llval, tcx.types.usize)
}

_ => span_bug!(span, "{:?} in constant", rvalue)
};

Expand Down Expand Up @@ -870,6 +876,7 @@ pub fn const_scalar_binop(op: mir::BinOp,
llvm::LLVMConstICmp(cmp, lhs, rhs)
}
}
mir::BinOp::Offset => unreachable!("BinOp::Offset in const-eval!")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/mir/operand.rs
Expand Up @@ -114,7 +114,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {

pub fn deref(self) -> LvalueRef<'tcx> {
let projected_ty = self.ty.builtin_deref(true, ty::NoPreference)
.unwrap().ty;
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
let (llptr, llextra) = match self.val {
OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()),
OperandValue::Pair(llptr, llextra) => (llptr, llextra),
Expand Down
15 changes: 13 additions & 2 deletions src/librustc_trans/mir/rvalue.rs
Expand Up @@ -432,7 +432,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
})
}

mir::Rvalue::Box(content_ty) => {
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
assert!(bcx.ccx.shared().type_is_sized(ty));
let val = C_uint(bcx.ccx, bcx.ccx.size_of(ty));
let tcx = bcx.tcx();
(bcx, OperandRef {
val: OperandValue::Immediate(val),
ty: tcx.types.usize,
})
}

mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
let llty = type_of::type_of(bcx.ccx, content_ty);
let llsize = machine::llsize_of(bcx.ccx, llty);
Expand Down Expand Up @@ -515,6 +525,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::BinOp::BitOr => bcx.or(lhs, rhs),
mir::BinOp::BitAnd => bcx.and(lhs, rhs),
mir::BinOp::BitXor => bcx.xor(lhs, rhs),
mir::BinOp::Offset => bcx.inbounds_gep(lhs, &[rhs]),
mir::BinOp::Shl => common::build_unchecked_lshift(bcx, lhs, rhs),
mir::BinOp::Shr => common::build_unchecked_rshift(bcx, input_ty, lhs, rhs),
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
Expand Down Expand Up @@ -660,7 +671,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::Rvalue::CheckedBinaryOp(..) |
mir::Rvalue::UnaryOp(..) |
mir::Rvalue::Discriminant(..) |
mir::Rvalue::Box(..) |
mir::Rvalue::NullaryOp(..) |
mir::Rvalue::Use(..) => // (*)
true,
mir::Rvalue::Repeat(..) |
Expand Down
14 changes: 9 additions & 5 deletions src/rustllvm/RustWrapper.cpp
Expand Up @@ -781,11 +781,15 @@ extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
RustStringRef Str) {
RawRustStringOstream OS(Str);
OS << "(";
unwrap<llvm::Value>(V)->getType()->print(OS);
OS << ":";
unwrap<llvm::Value>(V)->print(OS);
OS << ")";
if (!V) {
OS << "(null)";
} else {
OS << "(";
unwrap<llvm::Value>(V)->getType()->print(OS);
OS << ":";
unwrap<llvm::Value>(V)->print(OS);
OS << ")";
}
}

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

0 comments on commit 7b295ee

Please sign in to comment.