Skip to content

Commit db25210

Browse files
committed
auto merge of rust-lang#5044 : thestinger/rust/range, r=pcwalton
Closes rust-lang#4924 There are some more `Load` calls that could use this, so it's not completely done yet.
2 parents b88e4f3 + fa6e3b4 commit db25210

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

src/librustc/lib/llvm.rs

+9
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,15 @@ pub enum FileType {
184184
ObjectFile = 1
185185
}
186186

187+
pub enum Metadata {
188+
MD_dbg = 0,
189+
MD_tbaa = 1,
190+
MD_prof = 2,
191+
MD_fpmath = 3,
192+
MD_range = 4,
193+
MD_tbaa_struct = 5
194+
}
195+
187196
// Opaque pointer types
188197
pub enum Module_opaque {}
189198
pub type ModuleRef = *Module_opaque;

src/librustc/middle/trans/_match.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -1361,13 +1361,29 @@ pub fn compile_submatch(bcx: block,
13611361
if opts.len() > 0u {
13621362
match opts[0] {
13631363
var(_, vdef) => {
1364-
if (*ty::enum_variants(tcx, vdef.enm)).len() == 1u {
1364+
let variants = ty::enum_variants(tcx, vdef.enm);
1365+
if variants.len() == 1 {
13651366
kind = single;
13661367
} else {
13671368
let enumptr =
13681369
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
13691370
let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
1370-
test_val = Load(bcx, discrimptr);
1371+
1372+
1373+
assert variants.len() > 1;
1374+
let min_discrim = do variants.foldr(0) |&x, y| {
1375+
int::min(x.disr_val, y)
1376+
};
1377+
let max_discrim = do variants.foldr(0) |&x, y| {
1378+
int::max(x.disr_val, y)
1379+
};
1380+
1381+
test_val = LoadRangeAssert(bcx, discrimptr,
1382+
min_discrim as c_ulonglong,
1383+
(max_discrim + 1)
1384+
as c_ulonglong,
1385+
lib::llvm::True);
1386+
13711387
kind = switch;
13721388
}
13731389
}

src/librustc/middle/trans/build.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ use lib::llvm::llvm;
1414
use lib::llvm::{CallConv, TypeKind, AtomicBinOp, AtomicOrdering};
1515
use lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False};
1616
use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
17-
use libc::{c_uint, c_int};
17+
use libc::{c_uint, c_int, c_ulonglong};
1818
use middle::trans::common::*;
19+
use middle::trans::machine::llsize_of_real;
1920

2021
use core::cast::transmute;
2122
use core::cast;
@@ -536,6 +537,25 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
536537
}
537538
}
538539
540+
pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
541+
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
542+
let value = Load(cx, PointerVal);
543+
544+
unsafe {
545+
let t = llvm::LLVMGetElementType(llvm::LLVMTypeOf(PointerVal));
546+
let min = llvm::LLVMConstInt(t, lo, signed);
547+
let max = llvm::LLVMConstInt(t, hi, signed);
548+
549+
550+
do vec::as_imm_buf([min, max]) |ptr, len| {
551+
llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
552+
llvm::LLVMMDNode(ptr, len as c_uint));
553+
}
554+
}
555+
556+
value
557+
}
558+
539559
pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
540560
unsafe {
541561
if cx.unreachable { return; }

src/librustc/middle/trans/datum.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,13 @@ pub impl Datum {
431431
} else {
432432
match self.mode {
433433
ByValue => self.val,
434-
ByRef => Load(bcx, self.val)
434+
ByRef => {
435+
if ty::type_is_bool(self.ty) {
436+
LoadRangeAssert(bcx, self.val, 0, 2, lib::llvm::True)
437+
} else {
438+
Load(bcx, self.val)
439+
}
440+
}
435441
}
436442
}
437443
}

0 commit comments

Comments
 (0)